Wann machen Interfaces Sinn? Wann Custom Events?

  • Ich hoffe mir kann einer mal erklären, wann Interfaces und wann Custom Events (nenne ich einfach nur Event) besser sind.
    Bevor wieder irgendeiner meint, dass Events nicht gut sind, weil sie an den falschen Actor gehn, damit hatte ich nie Probleme, wozu gibt es ein Castto, mit dem man überprüft ob der Actor auch wirklich ein "Gegner" ist...



    In meinem derzeitigen Projekt mach ich alles mit Events, find ich einfach übersichtlicher, man platziert ein Event, called es in nem andern BP und wenn man später das passende Gegenstück sucht, klickt man entweder auf den Caller doppelt und kommt an die richtige Stelle oder man sucht die Referenzen ab.
    Sollte ich Interfaces benutzen, hab ich immer das Problem, dass ich mich dumm und dämlich suchen kann ... nicht mal über die Referenz-Suche findet man den richtigen Part.



    Derzeit ist es bei mir so, dass ich im Player Character nen Trace mache, den Hit_Actor als Variable speichere und dann noch aufn Enemy_BP caste, um rauszufinden ob es wirklich ein Gegner ist, den man grad anvisiert.
    Danach wird ein Projektil gespawnt, welchem ich dann mit einem Event alle nützlichen Daten weiter gebe.
    Im Projektil wird alles berechnet und dann mit "Apply Damage" oder "Apply Radial Damage with Falloff" an den Gegner weiter gegeben und das Projektil zerstört.
    Im Gegner selber wird dann nur noch der Schaden vom Leben abgezogen, der Damage-Text gespawnt und bei <=0 Leben, zerstört.



    In einem Beispiel DamageText Projekt (vom orig. UE4 Forum), wird egal was, immer nur mit Interfaces gemacht, da wird nicht mal das "Apply Damage" benutzt, sondern ein eigenes Interface um den Schaden vom Projektil zum Gegner weiter zu geben und der Schaden dann direkt im Gegner berechnet, was ich extrem dämlich finde...


    Wobei der Character dort überhaupt keine Werte besitzt, mein Character hat dagegen noch einige Multiplikatoren auf Lager, wegen Rüssi und Waffen und das Projektil hat auch noch eigene Werte^^

    3 Mal editiert, zuletzt von Killerzwerg ()

    • Offizieller Beitrag

    Wenn du ein SpawnActor nutzt und eine Class Datei selbst dort einrichtest, dann hast du den direkten Pfad zum Actor. Das siehst du auch am Output. zb Hier habe ich Character ausgewählt und am Output sieht man ein Character Object. Nun könnte ich alle Funktionen und Variablen im gespawnten Actor nach dem Return manipulieren.


    Mach mal für Class Input eine Variable und stell die Variable auf Charakter ein. Schon siehst du, der Output ist nur noch ein Actor Object. Damit kannst du sogut wie nix anfangen. Du kannst keine Funktionen und Variable aufrufen, die im gespawnten Actor vorhanden sind. Dies passiert daher, weil NewVar0 eine Dynamische Variable ist. Diese Variable kann jeder ändern. Von daher weiss das BP auch nicht, welche Class Datei geladen wird. Desswegen gibt es Interfaces.


    Mit ein Interface kannst du, wenn dieses Interface im gespawnten Actor eingerichtet ist, beliebig alle Funktionen und Variablen ändern. nur das Interface muss im Actor richtig programmiert sein, also alles nötige was man braucht. Auch Events sind im Interface aktivierbar, die im Actor eingerichtet sind.


    Bei einem Event, oder Custom Event kannst du gerne mit CastTo arbeiten. Weis aber dein BP Programm von deiner Zauberkugel nicht, wen es trifft, dann kannst du mit dem getroffenen Actor nichts anfangen. zb es gibt 2 verschiedene Monster. Monster 1 heißt Eliot, und Monster 2 heißt Raffzahn. Wenn die Kugel ein monster trifft, dann will man an die Lebenspunkte.
    ActorBeginOverlap hat nur ein ActorObject Output. Dies bringt nichts viel.


    Nun hat man diese Möglichkeit. CastTo übermittelt dem BP den richtigen Pfad zur Class Datei und man hat vollen Zugriff. Stell dir vor, du hast nicht nur 2 Monster, sondern 1000 verschiedene Monster. Willst du dann 1000 mal CastTo erstellen? Das will kein Programmierer. Deswegen gibt es Interfaces. Man hätte aber auch die Möglichkeit ein Monster Actor zu erstellen und dieses Actor generiert den Skeletal Mesh den es benötigt und somit hast du nur ein Actor, mit dem du CastTo ansprechen könntest. Das wäre aber ein riesiges BP Disaster, da für jedes Monsterverhalten ein Programm geschrieben werden muss und das alles in einem Actor?


    Deswegen geht man so vor: Man erstellt ein eigenes Interface, dass nur dafür dient und im jedes Monster Actor wird dieses Interface eingebunden. Nur noch für dieses Interface eine Funktion erstellen und das wars. Damit ein Interface überhaupt funktioniert, muss am Output im Interface eine Variable als Output erstellt werden. Ich habe keine Idee, warum das so ist, aber erst wenn 2 Nodes, also Input und Output exestieren, dann funktioniert auch das Interface und es erscheint im Actor, wo es implementiert wird.

  • Event=Ereignis und Interface=Schnittstelle. Bisweilen haben die für micht garnichts miteinander zu tun als das sie nacheinander behandelt werden aber nicht zu vergleichen sind.


    Das Vorgehen aus dem UnrealForum ist hinsichtlich des Interfaces richtig. Dahinter steckt eine Programmierlogik. Events werden da abgehandelt, wo sie auftreten. Die Schadensberechnung wird beim Gegner durchgeführt. Die Schadensursache wird übermittelt. Die "Munition" ist letztlich nur Grafik.


    CustomEvents dienen in erster Linie dazu, verschiedene Situationen zu differenzieren (verschiedene Events). Jedes differenzierbare Ereignis kann mit einem Event verbunden werden, sodass man am Ende der Übersichtlichkeit Rechnung trägt.


    Einfachstes Event ist "Benutzen/Use". Man implementiert dieses Event in jeden Actor, der eine Benutzung zulässt. Die Benutzung kann dann im jeweiligen Actor angepasst werden. Bsp: öffne Tür, öffne Kiste, trinke Wasser, ziehe am Hebel. Das Interface vermeldet aber immer nur im anvisierten Objekt die as UseEvent. Gibt es ein solches Event im anvisierten Actor nicht, passiert nichts.


    Da man das Event vorprüfen kann, funktionieren so auch Tastenbelegungen unter verschiedenen Bedingungen. Befinde ich mich also beispielsweise in einem Baumenü oder in der Übersichtskarte, so kann bspw "E-Key" eine andere Funktion (Event) auslösen als das typische UseEvent. Genauso kann ich Prüfungen vorschalten, wenn die Maus über bestimmten Objekten liegt, also das Trace einen spezifizierten Actor ausgibt (IF-Abfrage/Select).

  • Das Problem ist, dass ich alle eure Beispiele auch mit nem stinknormalen Custom Event hin kriege...
    Und so wie @Dj EKI meinte, dass man 1000 Cast to für 1000 Monster braucht, stimmt nicht, ich hab einen Master_Enemy und viele Childs, das geht damit wunderbar.
    Bei der Tastenbelegung hab ich immer direkt ein Bool gesetzt, um einer Taste, verschiedene Funktionen zu geben...


    Wenn man was spawnt, mach ich es immer mit diesem Return Value, hatte damit auch nie Probleme^^



    Das einzige was nachvollziehbar ist, wenn man mehrere "verschiedene" Actor mit der gleichen Funktion hat.


    Gibt es vielleicht Performance-Vorteile wenn man statt Custom Events, Interfaces implementiert?

  • Um den Performance Vorteil zu messen kann man den "Profiler" nutzen aber das ist wieder ein Thema zu dem man ein ganzes Buch schreiben könnte.


    Grundsätzlich - was funktioniert ist legitim. End of Story. Klar gehen manche Sachen schneller oder besser mt anderen Methoden - einfach mal probieren statt studieren. Wenn du compilierst kannst du ja mal nach C++ kompilieren - das macht teilweise Welten unterschied wenn du lahme Blueprints zu c++ kompilierst - siehst du aber erst dann wenn du kompiliert hast. Meist ist das kompilieren nach C++ aber ein echter Gewinn also aus Performance Gründen wert zu probieren.

  • In deinem Beispiel wäre ein Interface wirklich nicht nötig, da alle von der selben Basisklasse erben
    Ist dies nicht möglich z.B. Charaktere, Projektile, Props sollen eine gemeinsame Schnittstelle bekommen, dann ist ein Interface super.


    Unter der Haube also in C++ ist das einfach multiple Vererbung.