Hilfe! Weiterleitung mit Cast to.... schlägt fehl

  • HalliHallo,
    ich lese hier schon seit einiger Zeit fleißig mit und auch wenn ich noch neu in Sachen unreal engine bin, habe ich schon einige Schaltungen gebastelt und komme eigentlich ganz gut klar. Ich wollte mich nun aber doch mal endlich hier anmelden, nicht zuletzt, weil mir eine Frage auf der Seele brennt.
    Es geht um das "Cast to..." Blueprint. Ich habe zwar schon einige Weiterleitungen hinbekommen, nur will bei mir die Weiterleitung zu einem Actor nie funktionieren. Wenn ich "Event Overlap" benutze verbinde ich den Objecteingang des "Cast Blueprint" und den Ausgang "other actor" vom "Event Overlap" einfach miteinander. Das kann ich aber nicht einfach so stehen lassen, weil ich es verstehen möchte.
    Wenn ich aber normal zu einem Actor Casten möchte, funktioniert gar nichts. Was ich immer wieder lese ist, dass da eine Referenz zwischen beiden Blueprints dran muss. Aber wie genau sieht diese Referenz aus? Wie und wo erstelle ich diese Referenz? Wenn ich eine "Components" vom Zielblueprint anschließe kommt auch eine Fehlermeldung im "Cast to...". Wenn ich ein"Get... " anschließe kommt auch eine Fehlermeldung. (das funktioniert allerdings komischerweise, wenn ich zum Character caste) Ich hoffe ihr könnt es mir verständlich erklären. Egal was ich darüber gelesen habe, habe ich leider nicht verstanden. Ich weiß nur, dass das essentiell für eine Spieleentwicklung ist. Schonmal danke im voraus

    • MfG Ulrich
  • Wenn ich es richtig rauslese verstehst du Grundlegend den Cast falsch.


    Ich hoffe du weißt schon dass Klassen Eigenschaften, Methoden und Funktionen von anderen Klassen erben und überladen können. (Stichwort: Polymorphie, vielleicht hat wer im Forum was gute dazu, den wikipedia artikel mag ich dazu nicht so gerne, der ist zwar richtig, aber zu technisch)


    Jedes Objekt in UE4 (in Blueprint, alle Variablen die Hell-Blau sind) basiert auf der Klasse UObject. UObject kannst du sozusagen als die niedrigste und einfachste Klasse an Objekten sehen, auf der alle anderen komplizierteren Klassen aufbauen.
    Jede Variable die in Blueprint als Typ die Klasse eines Objektes haben beinhalten eigentlich nicht das Objekt selbst, sondern sind Zeiger, welche auf den Bereich im Arbeitsspeicher zeigen, wo dieses Objekt abgelegt ist.
    Damit ein Programm aber Daten auf dem Speicher verarbeiten kann, muss es natürlich wissen was das für Daten sind. Hier kommt der Typ ins Spiel. D.h. damit der Zeiger weiß, dass er gerade auf ein Objekt zeigt oder ein Actor zeigt muss er wissen dass er ein Zeiger auf Daten vom Typ X ist.


    Jetzt kommt eine Eigenschaft der Polymorphie ins Spiel. Nehmen wir uns einen Actor. Ein Actor ist automatisch auch ein UObject, da es ja auf dieser Klasse basiert. D.h. ein "UObject"-Zeiger der auf den Actor zeigt kann auch erfolgreich genutzt werden. Jedoch weiß der Zeiger nur dass es ein UObject oder höher ist. D.h. der Zeiger erlaubt nur Zugriff auf die Eigenschaften die der Actor von UObject geerbt hat.


    Jetzt kommt das Casting ins Spiel. Casting ist das umwandeln des Zeigers in einen anderen Typ. (Upcasting = Umwandeln in einen Zeiger von höherwertigem Typ, Downcasting = Umwandeln in einen Zeiger von niedrigerem Typ)
    Dein UObject-Zeiger zeigt auf einen Actor. Du kannst aber wie erklärt mit diesem nur auf die Eigenschaften eines UObjects zugreifen. Jetzt möchtest du aber gerne auch mal auf die Eigenschaften eines Actors zugreifen können. Was du also machst ist dass du den UObject-Zeiger in einen Actor-Zeiger castest. Intern passiert da nicht viel, es wird nur ein neuer Zeiger auf die gleiche Speicheraddresse erstellt nur wird ihm gesagt, dass er auf einen Actor zeigt. In Blueprint funktioniert das ganze etwas smarter, falls das casting erfolgreich ist (also wenn das Objekt auf was zu zeigst tatsächlich ein Actor oder höher ist) hast du einen Zeiger der dir Zugriff auf die Eigenschaften eines Actors bietet. Der Cast zu einem Actor ist nicht erfolgreich wenn das Objekt kein Actor ist oder nicht von Actor erbt.


    Ich hoffe das ist halbwegs verständlich. Bei der Thematik kann man wahrscheinlich ein ganzes Kapitel füllen, da eigentlich so einige Konzepte wie OOP, Polymorphie vorher eingeführt werden müssen. An sich kann man OOP und Polymorphie aber gut verstehen, weil es programmierung weniger abstrakt macht.
    Falls du etwas nicht verstehst gerne nachfragen.

  • Das hilft mir schonmal die Sache zu verstehen, zumindest die Theorie. Danke. Aber was bedeutet das konkret in der Engine? Ich weiß, dass es einige nicht gerne sehen, wenn man sich genaue Beispiele wünscht, muss allerdings sagen, dass ich dann besser verstehe.
    Ich habe einen Character und möchte zu einer Lampe(ist ein blueprint) Casten. Habe ein Event tick im Character, an diesen habe ich ein "Cast to.. Lampe" geschaltet. Für den Object Eingang habe ich im Character eine variable erstellt(LampeTest). Im Details Bereich habe ich bei "Variable Type" dann Lampe->Object Reference ausgewählt und diese variable an den Object Eingang des "Cast to Lampe" gestöpselt. Dann kommt folgende Meldung: "" LampeTest"" is alredy a Lampe, you don't need cast to Lampe". Habe das Gefühl, dass ich auf dem richtigen Weg bin, aber irgendwie muss ich dieser Variablen noch sagen, dass sie auch fehlschlagen kann oder? Wenn ich komplett auf dem Holzweg bin, bitte Schritt für Schritt erklären, wie ich dem cast erfolgreich anschließe. Erst danach kann ich mich um das Verständnis insgesamt kümmern.

  • Wenn die blaue Meldung kommt, dass die Lampe bereits ne Lampe ist, dann brauchst du nicht zu casten, sondern kannst einfach die Daten aus der Variable ändern^^
    Falls du jedoch dann eine Meldung kriegst, dass die Lampe nicht existiert (oder so ähnlich), dann pack die Variable noch in ein "IsValid?" rein, wenn valid, also verfügbar, kannst die Daten ändern, wenn nicht valid, schlägt es fehl.

  • Wenn die blaue Meldung kommt, dass die Lampe bereits ne Lampe ist, dann brauchst du nicht zu casten, sondern kannst einfach die Daten aus der Variable ändern^^

    Aber dann habe ich doch absolut immer das Problem, wenn ich wie oben geschildert eine Variable erstelle und dann unter Details "Variable Type->Lampe" die Zuweisung mache. Wenn ich jetzt von einem Character zur Waffe Casten möchte, kommt doch dann diese Meldung wieder!? Diese Referenz muss doch irgendwie anders gehen/einzustellen sein.


    Ich möchte doch aber wissen, ob ich eine Pistole, eine Shotgun, oder ein Sturmgewehr aufhebe (nur als Beispiel). Und da muss doch der Cast bei der Shotgun fehlschlagen, wenn ich auf einem Sturmgewehr stehe.


    Ich möchte doch fürs erste nur wissen, was ich genau klicken muss, damit keine Meldung mehr an meinem "Cast to.." kommt

  • Du bist nicht ganz richtig. Aber erstmal eine kleine Anmerkung zu dem hier:

    Habe ein Event tick im Character, an diesen habe ich ein "Cast to.. Lampe"

    Bitte nicht jeden Tick casten. Da es sich um eine Lampe handelt reicht einmal casten und anschließendes speichern in einer Variable komplett.



    Object Eingang habe ich im Character eine variable erstellt(LampeTest).

    Wenn ich das richtig verstehe, dann hast du hier eine Variable vom Typ "Lampe" erstellt die du dann zum Typ "Lampe" casten willst. Das macht wie Killerzwerg gesagt hat keinen Sinn, da es bereits eine Lampe ist.

    aber irgendwie muss ich dieser Variablen noch sagen, dass sie auch fehlschlagen kann oder?

    In diesem Fall nein. In einer Variable vom Typ "Lampe" kannst du ausschließlich nur Objekte vom Typ "Lampe" speichern. Das heißt es ist immer eine Lampe.


    Wenn du dein Beispiel richtig stellen willst musst du folgendermaßen vorgehen:


    1. Erstell eine Input Variable vom Typ "Actor".
    2. Speicher eine Objekt vom Typ "Lampe" in der "Input" (Hierbei handelt es sich um einen Upcast von "Lampe" -> "Actor". In Unreal ist es nicht notwendig einen Upcast zu machen, weshalb du dir hier die "CastTo" node sparen kannst)
    3. Erstelle eine Output Variable vom Typ "Lampe"
    4. Nun ziehst du die "Input" Variable in den Input von der CastTo Node und castest diese zu "Lampe". Den Output kannst du dann in der Output Variable speicher.


    In diesem Beispiel kann der Cast auch fehlschlagen da du in einer Variable vom Typ Actor theoretisch auch ein Objekt "Tisch" speichern könntest. Würdest du das tun, würde der Cast fehlschlagen.


    Hoffe ich konnte dir damit weiter helfen.

  • Es zeigt jetzt zwar keine Fehlermeldung mehr an, aber der Print String zeigt mir, dass das "Cast to.." trotzdem dauerhaft fehl schlägt

    2. Speicher eine Objekt vom Typ "Lampe" in der "Input" (Hierbei handelt es sich um einen Upcast von "Lampe" -> "Actor". In Unreal ist es nicht notwendig einen Upcast zu machen, weshalb du dir hier die "CastTo" node sparen kannst)

    Diesen Schritt hier hab ich ausgelassen. War das richtig? Falls ich den machen muss, kannst du mir erklären, was du mit "Speicher ein Objekt vom Typ "Lampe" in der "Input"" meinst? Habe da keinen Ansatz, wie ich ein Objekt im Typ Lampe abspeichere.


    Ansonsten erstmal ein großes Dankeschön. Das erste mal, dass ich eine Schritt für Schritt abfolge im Internet lese. Dieses Problem scheint das bestgehütete Geheimnis unter den "Cast to.."-Verständigern zu sein^^

  • Ich tendiere tatsächlich dazu in einer Step by Step Anleitung nur notwendige Schritte einzubauen:D. Also ja, dieser Schritt ist notwendig.


    Okay ich beschreibe Punkt 2 nochmal etwas genauer.


    2.1 Du ziehst die erstellte Input Variable in den Blueprint und wählst dann "Set" aus.
    2.2 Du benutzt "Construct Object from Class" (Bin hier nich ganz sicher wie der heisst aber fängt sicher mit Construct Object... anfängt" und erstellst dir dann ein Objekt vom Typ "Lampe"
    2.3 die erstellung erfordert glaub ich sowas wie position etc. das musst dann halt setzen damit du überhaupt ein objekt erstellen kannst.
    2.4 du ziehst das erstellte Objekt in den Set von Input


    Damit hast du ein Objekt Lampe in einer Variable vom Typ Actor gespeichert. (Wie bereits erwähnt handelt es sich hierbei um einen Upcast)

  • Sorry für die Späte Antwort. Musste erstmal meinen Verpflichtungen nachgehen leider^^


    Tut mir leid wenn ich mich so blöd anstelle, aber jetzt kommt eine Fehlermeldung in dem "Construct Object". Ich habe mal zwei Bilder angehängt, damit du meinen peinlichen Versuch siehst. Die InputVariable habe ich einfahc mal "InputActor" genannt und zum Typ Actor gemacht. Die OutputVariable habe ich VariableLampe genannt und habe sie Typ Lampe zugewiesen. Das möchte ich gerne zu einem Custom event führen (Das Gegenstück des CustomEvents, ist in der Lampe und hängt an einem Print String.

  • Sorry mein Fehler.


    Da die Lampe ja ein Actor ist kannst du auch die "Spawn Actor" Node anstelle von "Construct Object" verwenden:


    Hier ein Beispielbild:[Blockierte Grafik: https://answers.unrealengine.com/storage/temp/23191-bp1.jpg]


    Hierbei musst halt ne Transform mitgeben damit der Actor weiss wo er Spawnen muss.


    Damit wäre das Beispiel korrekt.


    Testweise kannst danach auch noch nen anderen Actor erstellen, in dem Input speicher und dann versuchen nach Lampe zu casten. In diesem Fall wird die Cast Failed ausgelöst.


    Damit hättest du mal ein kleines Beispiel wie Cast to funktioniert.


    Wichtig zu wissen ist:
    Cast To kann nicht aus einer Lampe einen Tisch machen.


    Wenn du das Prinzip von Casten und deren Zweck wirklich verstehen willst musst du dich leider etwas tiefer mit Objektorientierung auseinandersetzen. Wie Tomura bereits erklärt hat geht dies nicht mal eben kurz in einem Thread.

  • Ich möchte mal versuchen meine Frage anders zu stellen:


    Wenn ich mein Beispiel aufgreife mit dem Character und der Lampe und ich habe diesmal VON der Lampoe ZUM Character Casten möchte, dann schließe ich an dem Objecteingang des "Cast to..." ein "Get Player Pawn" an und das Signal wird zum CustomEvent im Character weiter geleitet und es funktioniert. Siehe Bild 1


    Wenn ich VON Character ZUR Lampe Casten möchte, benötige ich komischerweise ein Event, dass als Output "other Actor" besitzt. Ich schließe den an den ObjectInput des "Cast to..." und es funktioniert. Das Signal wird zum Custom Event zur Lampe weitergeletet. Siehe Bild 2


    Ich könnte noch mehr beispiele bringen (Mit KI funktioniert das ja auch so), in dem es möglich ist so zu casten. Aber manchmal braucht man auch die Möglichkeit zu einem Actor/Blueprint zu casten, ohne das man solche Anschlüsse in den Events hat. Siehe Bild 3


    Gibt es da echt keine einfache Möglichkeit an den ObjectInput des "Cast to.." eine Referenz zu erstellen, damit das Signal über das CustomEvent zur Lampe weitergeleitet wird? Sowas wie "Get Actor Pawn" existiert ja komischerweise nicht in der Engine, wie für den Character, oder der KI


    ps.: Ich weiß, das EventTick ist unglücklich. Es dient nur zur Veranschaulichung :P


    Danke für deine Mühe, ich weiß das wirklich zu schätzen!










  • Aber manchmal braucht man auch die Möglichkeit zu einem Actor/Blueprint zu casten, ohne das man solche Anschlüsse in den Events hat

    Wozu brauchst du das, gebe uns mal ein konkretes Beispiel.


    Um mal bei Deiner Lampe zu bleiben, davon gibt es ja sicherlich nicht nur eine. Woher soll die Engine den wissen welche Du meinst. Dazu brauch sie aber ein existierendes Objekt.
    Dein Lampen Blueprint im Content Browser ist nur eine Schablone nach der die einzelnen Objekte gebaut werden.

  • Du benutzt Cast to Grundsätzlich falsch

    Achso, ich habe das in meiner kurzen Lernzeit so verstanden, dass das Cast to... dazu verwendet wird, um zwischen Blueprints kommunizieren zu können, egal welche Art dieses Blueprint ist.



    Wozu brauchst du das, gebe uns mal ein konkretes Beispiel.

    Sory bin da noch Anfänger. Aber nehmen wir an man hat eine Waffe. Diese Waffe hat Munition. Und die noch vorhandenen Kugeln im Magazin soll auf dem Bildschirm angezeigt werden. Also muss doch von dem Widget zur Waffe gecastet werden. Die Waffe fungiert doch in diesem Beispiel als Actor oder? Also im Widget, Cast to Waffe. Und da bin ich wieder vor dem Problem, dass es ja anscheinend nicht geht.



    Um mal bei Deiner Lampe zu bleiben, davon gibt es ja sicherlich nicht nur eine. Woher soll die Engine den wissen welche Du meinst. Dazu brauch sie aber ein existierendes Objekt.
    Dein Lampen Blueprint im Content Browser ist nur eine Schablone nach der die einzelnen Objekte gebaut werden.

    Ist meine Lampe (ist ja nur ein Beispiel damit ich das verstehe) denn kein Objekt? Das mein Lampenblueprint eine Schablone ist, habe ich, denke ich verstanden. Setze ich allerdings mehrere Lampen, wird quasi das programmierte Blueprint auf jede Lampe einzeln "übertragen". Kenne die Fachwörter noch nicht. Aber ich dachte bisher, dass das dann das Objekt ist?

  • Also muss doch von dem Widget zur Waffe gecastet werden.

    Nein,


    Dein Widget ist keine Waffe und kann damit auch nicht zu einer Waffe werden.


    Was du brauchst ist eine Referenz im Widget die auf die Waffe zeigt. Über diese kannst du dann mit der Waffe kommunizieren und Werte auslesen. Wie du im Widget zu dieser Referenz kommst ist eine andere Frage.


    Wenn dein Character zb eine Waffe hält, dann kannst du die Waffe vom Character aus Spawnen lassen --> Der Character hat dann eine Referenz zu dieser Waffe. Um nun vom Widget an diese Referenz zu kommen könntest du folgendermaßen vorgehen:


    getPawn (das ist der Character) --> castTo Character --> Waffenreferenz --> call Event auf der Waffe.



    Wie du deine Referenzen organisierst & was das optimale Design ist kommt dann wieder auf dich an. Hier müsstest du dich mal in Design-Patterns einlesen und bissle probieren. Sowas braucht aber Übung.


    Alternativ kann man es natürlich drauf pfeifen und irgendwas zusammen wursteln. Das kann auch funktionieren, ist dann aber sehr schwierig zu erweitern und zu warten.

  • Sory bin da noch Anfänger. Aber nehmen wir an man hat eine Waffe. Diese Waffe hat Munition. Und die noch vorhandenen Kugeln im Magazin soll auf dem Bildschirm angezeigt werden. Also muss doch von dem Widget zur Waffe gecastet werden. Die Waffe fungiert doch in diesem Beispiel als Actor oder? Also im Widget, Cast to Waffe. Und da bin ich wieder vor dem Problem, dass es ja anscheinend nicht ge

    Es gibt natürlich verschiedene Wege so etwas zu lösen.


    Wenn man eine Waffe aufnimmst liest man die Munition aus und speichert sie in einer Variable im Player. Bei jedem Schuss wird diese runtergezählt.
    Wird die Waffe weggeworfen schreibt man die aktuelle Monitionsmenge wieder in die Variable der Waffe.


    Dein Widget liest den Munitionsstand direkt vom Player und muss von der Waffe nichts wissen.

  • Vielleicht hilft dir dieses Unreal Tut noch weiter:


    Externer Inhalt www.youtube.com
    Inhalte von externen Seiten werden ohne Ihre Zustimmung nicht automatisch geladen und angezeigt.
    Durch die Aktivierung der externen Inhalte erklären Sie sich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.



    Hier geht es darum wie er ein Licht erstellt wird und der Character es ein und ausschalten kann.


    In den nachfolgenden Vids wird dann gezeigt wie du ausserhalb vom LevelBP das Selbe erreichen kannst.

  • Ok die Videos werde ich mir definitiv mal anschauen. Aber so ganz falsch habe ich doch das Cast to.. nicht verwendet oder? Selbst im Buch "Spiele entwickeln mit Unreal Engine 4" von Jonas Richartz wird beschrieben, dass das Cast to für "eine direkte Kommunikation zwischen zwei Blueprints" verwendet wird. Nur leider zeigt er nicht wie das zwischen 2 Objekten/Actors/Blueprints genacht wird.


    Ich werde mich jetzt erstmal, dank euren zahlreichen Hilfen, versuchen da durchzukämpfen und es zu verstehen. Ich werde außerdem versuchen was auf die Beine zu stellen.


    Wenn es recht ist würde ich im richtigen Projekt dann wieder hier rein schreiben, sobald ich mit diesem Thema wieder Hilfe benötige. Verstanden habe ich das irgendwie noch gar nicht leider


    Vielen Dank für eure Hilfe bisher!!! Habe ein paar likes da gelassen :)