Variable in anderem Blueprint

  • Moin, :pinguin:


    ich schätze mal das es total einfach ist, aber irgendwie check ich es nicht.


    Folgendes:
    Ich hab in einem Blueprint Eine "Name" Variable. Diese Variable ändert sich aber durch bestimmte Sachen immer wieder und wird später durch andere Sachen näher festgelegt.

    Was ich nun Versuche ist diesen Namen einem Charakter zuzuweisen.

    Ein Widget habe ich schon erstellt und den "Text Block" auch schon gebindet. Allerdings weiß ich nicht so recht wie ich jetzt die Variable aus dem anderen Blueprint jetzt in dieses Widget bekomme.

    Bis jetzt wird der Charakter im Spiel einfach nur mit "name" über dem Kopf angezeigt.

    Habe schon mehrere Videos geguckt aber irgendwie raffe ich es nicht so richtig,


    Kann mir da jemand weiterhelfen?

  • Von einem Blueprint ins andere kannst du mit "cast to" arbeiten um einen Aufruf zu starten. Du brauchst aber eine Referenz - die bekommst du entweder über den Spawn, actor placement (Hier kannst du aber nur im level bp eine referenz erstellen) oder über "get all actors" alle einsammeln. Du musst letztlich das Prinzip der Referenz verstehen um mit cast to sinnvoll BP übergreifend zu arbeiten.

  • Hey,


    danke für eure Antworten.

    Mit "GetActor of Class" hab ich es versucht, hat jetzt auch geklappt. Allerdings hab ich gestern es irgendwie verralt die Execution Pins auch zu connecten xD

    War wohl gestern einfach wieder viel zu spät. xD


    Vielen Dank^^

  • Kleine Warnung: Das ist in den meisten Fällen gaaaaaanz böse. Damit hast du nur zugriff auf den ersten Actor der damit gefunden wird. Dadurch ist ziemlich unvorhersehbar was dort passiert, wenn mehrere Instanzen des gleichen Typs existieren. Außerdem ist es eine sehr langsame Operation.


    Denk dir lieber aus wie du logisch auf genau den richtigen Character kommst.

    z.B. falls du dich in einem Widget befindest, dann hat dieser Widget bestimmt einen "Owning Player". Dieser "Owning Player" ist ein Player Controller, und dieser hat bestimmt einen Pawn. So bist du dir auch sicher, dass das Widget wirklich das Geld anzeigt, des Characters vom besitzer des Widgets. Das verhalten ist somit vorhersehbar.


    Handelt es sich z.B, um eine Component so kann man über den Owner gehen. Auch bei anderen Actors könnte es Sinn machen einen Owner zu setzen, damit man eine entsprechende Kette an Referenzen erzeugt.

  • Hey,


    vielleicht könnt ihr mir bei meinem neuen Problem auch weiterhelfen. Ich habe da irgendwo einen Logikfehler, mal wieder,


    Und zwar:


    Die Oben erwähnte Variable "Name" wird festgelegt durch einen Command im Chat.

    Wenn der Command im Chat getriggert wird. Erhalte ich sowohl den Namen als auch eine ID von demjenigen der den Command geschrieben hat.

    Daraufhin wird ein TPC in der Welt erstellt.

    Sollte der selbe User nochmal den Command benutzen wird kein zweiter TPC erstellt, da ich seine ID in einem Array abgespeichert habe und jedes mal wenn der Command benutzt wird geguckt wird ob die ID bereits in dem Array vorhanden ist.

    Sobald der TPC erstellt ist, setze ich den Namen in einer Variable fest und erzeuge ein Nameplate Widget das den Namen über den Charakter anzeigt.

    Im Widget suche ich also nach der Variable mit dem Namen, vergleiche diese mit dem Namen des Charakters, sollte dieser nicht übereinstimmen wird der Name geändert.

    Beispiel: User Paul benutzt den Command, es wird ein TPC erstellt mit den Namen Paul. User Chris benutzt den Command wird ein TPC Charakter mit dem Namen Chris erstellt.


    Allerdings wird bisher der Name von dem TPC Paul auch in Chris geändert und ich weiß nicht, wie ich es mache das sich der Name vom Paul nicht ändert.

    Ich schätze der Name ändert sich da die Variable ja geändert wird, aber wie sage ich dem ersten TCP den alten Namen zu behalten?


    EDIT: Mit kam grade der Gedanke, dass ich den Namen ja zusammen mit der ID in einem Array sammeln könnte. Wenn dann die ID noch nicht vohanden ist, wird ein TPC erstellt und der Name der zu der ID gehört wird in eine Variable gepackt. Ich weiß nur nicht wie ich dem Widget jedes einzelnden TPC der so erstellt wird, sage welche Varibale für ihn ist. Zumal ich nicht weiß, ob jedes so erstellte Widget als eins fungiert oder sich jedes dann wieder updatet, sobald ein neuer erstellt wird.

  • Daikota

    Da du ja das Widget nach dem erstellen des TPC erzeugst, Wäre es am sinnvollsten wenn des Widget eine Variable enthält in der eine Referenz zu einem TPC enthält. Sobald zu TPC und Widget spawnst, greifst du die Variable des Widgets ab und setzt sie entsprechend, da du in diesem Moment ja beide Objekte hast.

    So kannst du sehr einfach (und auch performance-technisch effizient) auf den Namen des TPC zugreifen.



    War nur ein Prototyp. Ausbaufähig halt. Ich hatte damit probiert dieses Cast To zu umgehen, was ich für eine sehr unlogische Lösung halte in einer objektorientierten Umgebung, bzw. widerspricht Cast To jeglichem OOP.


    Geht etwas am Thema vorbei aber :


    Cast to hat nichts mit OOP zu tun sondern Typisierung bzw. dem Type System. Blueprint hat wie C++ eine eher statische Typisierung mit Typenumwandlung . Der vorteil ist, dass die Typen von Variablen bzw. der Typ auf den ein Pointer zeigt zur Compilezeit bekannt ist. Das ermöglicht dass viele Probleme zur Übersetzungszeit erkannt werden. Dadurch dass man sehr präzise angeben muss um welchen Typ es sich bei einem Pointer handelt, ist sogar beim schreiben des Codes schon klar was man machen darf/kann und was nicht.

    Das Gegenstück wäre eine dynamische Typisierung (z.B. Javascript). Hier ist der Typ einer Variable nur während der Laufzeit bekannt bzw. aus dem Gesamtkontext des Programablaufs, statt einer Umwandlung muss man hier den Typ des Inhalts einer variable überprüfen um nicht in einen Fehler zu laufen (oder man überspring die Überprüfung basierend auf Annahmen).

  • Cast to hat nichts mit OOP zu tun sondern Typisierung bzw. dem Type System. Blueprint hat wie C++ eine eher statische Typisierung mit Typenumwandlung . Der vorteil ist, dass die Typen von Variablen bzw. der Typ auf den ein Pointer zeigt zur Compilezeit bekannt ist. Das ermöglicht dass viele Probleme zur Übersetzungszeit erkannt werden. Dadurch dass man sehr präzise angeben muss um welchen Typ es sich bei einem Pointer handelt, ist sogar beim schreiben des Codes schon klar was man machen darf/kann und was nicht.

    Das Gegenstück wäre eine dynamische Typisierung (z.B. Javascript). Hier ist der Typ einer Variable nur während der Laufzeit bekannt bzw. aus dem Gesamtkontext des Programablaufs, statt einer Umwandlung muss man hier den Typ des Inhalts einer variable überprüfen um nicht in einen Fehler zu laufen (oder man überspring die Überprüfung basierend auf Annahmen).

    Ja also Programmiersprachen mit untypisierten Variablen kann ich ja gar nicht so sehr drauf. Bei Cast To bin ich mir nie so sicher, wie das eigentlich umgesetzt ist. Gefühlt kommt es mir halt falsch vor.


    Beim OOP Programmieren ist es ja so das Variablen eine gewisse Sichtbarkeit haben. Also innerhalb einer Klasse, Funktion etc. Und auch bei jeder Programmiersprache wie C++ und C# etc. kann man diese Regel irgendwie umgehen, indem man die Philosophie von OOP umgeht. Das empfinde ich persönlich immer als relativ unsauber, auch wenn es nicht notgedrungen zu Fehlern führen muss. Aber auch damals, der berühmte Spagetticode, musste ja nicht unbedingt zu Fehlern führen. Und Cast To erzeugt bei mir immer so ein Gefühl als, wenn das so eine unsaubere Umgehung ist. Auch wenn ich zugegeben nicht immer drumherum komme es zu nutzen.

  • Mit dem CastTo wird doch nur überprüft ob das Objekt von einem bestimmten Type (BP-Klasse) ist und wenn ja bekommt man die Referenz.

    Ich würde es auch so stehen lassen, auch wenn Technisch was anderes passiert.

    Sehe es im Grunde so. Blueprint lässt nur zu auf Eigenschaften eines Objektes zuzugreifen, wenn es explizit gewährleistet ist, dass es sich um ein Objekt handelt was entsprechende Eigenschaft hat.

    Am Ende ist eine Variable auf ein Objekt in Blueprint eigentlich ein Addresszeiger auf ein Objekt einer bestimmten Klasse bzw. eines Kind der Klasse.


    Wenn du eine technische Erklärung brauchst zu dem was wirklich passiert, müsste ich etwas tiefer in C++ eingehen und wie Objekte im Speicher abgelegt werden und wie Pointer funktionieren, was glaube ich aber ein Text wird, für den ich länger brauchen werde.

  • Vielleicht liegt das ja auch an der Umsetzung der Cast To Node. Die macht in etwa den Eindruck einer REM-Zeile in alten Basicdialekten.

    Die Umsetzung entspricht in etwas einem dynamic_cast aus modernerem C++.

    Folgendes:

    Eine Object Variable in Blueprint ist eigentlich ein Pointer. Ein pointer ist eine Variable, die eigentlich nur eine Speicheradresse enthält (also eine 32 Bit oder 64 Bit Zahl). Im Falle eines Objektes zeigt ein Pointer auf die Adresse im Speicher an der das Objekt beginnt.

    Damit für den Compiler jedoch klar ist, auf was auf dieser Adresse eigentlich liegt hat ein Pointer wie eine normale Variable einen Typ. Nehmen wir an wir definieren unseren Pointer als einen "Parent-Parent-Pointer" (ich weiß das der Name doof ist, bin grad nicht kreativ)


    Jetzt wollen wir aber auch zugriff haben auf die Eigenschaften von Katze. Da wir den Zugriff auf under Katzen-Objekt aber nur über einen Tier-Pointer machen, können wir nicht sicher sein, ob unser Tier auch eine Katze ist.

    Da C++ eine statische Typisierung hat, können wir nicht einfach den Typ des Pointer verändern. Wir müssen einen neuen Pointer erzeugen, der auf die gleiche Adresse zeigt, aber vom Typ Katze ist.

    Bei einem Pointer vom Typ Katze können wir also sicher sein, dass auf der Adresse auch eine Katze liegt, sofern dieser überhaupt auf eine Adresse zeigt.



    Die Bilder beschreiben jetzt den Fall, dass es sich bei dem Objekt auf das gezeigt wird auch wirklich um eine Katze handelt. Ist dies nicht der Fall z.B. weil unser Tier ein Hund ist so resultiert der dynamic cast zwar auch in einen Pointer der auf eine Katze zeigen kann, jedoch zeigt dieser ein nullpointer, d.h. ein Pointer der auf Nichts zeigt. Denn ein Objekt vom Typ Hund ist keine Katze.

    An sich ist der Cast To in Blueprint so wie er ist, weil man es in C++ so macht. In C++ muss immer klar sein welchen Typ eine Variable hat oder auf was für eine Variable ein Pointer zeigt. Diese Information benötigt der Compiler um verstehen zu können was dort überhaupt passieren soll. Ein int 32 und ein float belegen ja z.B. genauso viel Speicher bedeuten aber was komplett anderes.

    C++ bietet noch andere möglichkeiten zum casten z.B. ohne Überprüfung, das macht meistens nicht viel Sinn, außer man will wirklich die Bits manipulieren oder ist auf Ärger aus.


    Falls hier etwas nicht stimmt oder zu ungenau ist, kann man bitte meckern, ich hab das ganze auch nur "on the fly" geschrieben.

  • Ich habe vor zig Jahren ja mal C, ohne ++ gelernt. Ein bisschen C++ kann ich zwar auch, aber mit dem modernen kann ich nichts anfangen, diese Schreibweisen mit :: usw. macht mir beim Lesen Kopfschmerzen. Aber damals fand ich die C Syntax recht schön, eine ganze Weile hatte C++ ja auch diese Syntax. Allerdings habe ich es damals zusammen mit Cobol gelernt, das sagt ja schon alles.


    Pointer usw. gab es damals ja auch schon. Ich weiß nur nicht mehr ob man auf Pointervariablen übergreifend zugreifen konnte/sollte.


    Aber wenn das alles OK ist, und kein Schmiercode, habe ich gegen Cast To nie etwas gesagt und behaupte ab jetzt das Gegenteil.

  • Damit für den Compiler jedoch klar ist, auf was auf dieser Adresse eigentlich liegt hat ein Pointer wie eine normale Variable einen Typ.

    Das Zeiger typisiert sind war mir neu. Eigentlich logisch, kann mich aber nicht entsinnen mal was davon gelesen zu haben in den üblichen Tutorials.


    Bin aber auch kein Programmierer und erst recht nicht in C++.


    Aber vielen Dank für diesen informativen Beitrag.