Beiträge von Tomura

    Wie kyodai sagt, ergibt sich das aus der Logik (ich will einen Kegel, von daher benötige ich ja die Richtung des Kegels und den Winkel) und aus den Variablen Namen.

    Zu C++ in UE4:

    Epic hat bei C++ die Philosophie, dass Code der keine Kommentare braucht, auch keine Kommentare bekommt. Das hält natürlich den Dokumentationsaufwand auf niedrigen Niveau und sorgt für einen konsistenten Programmierstil.


    Es hilft nicht direkt, aber du kannst dir mal den Coding Standard anschauen.

    https://docs.unrealengine.com/…mentSetup/CodingStandard/


    Hier mal ein Beispiel für Code der sich selber Dokumentiert. Da Epic so programmiert, genügt es oft, wenn man einfach in die Definition der Funktion reinschaut. Natürlich gegeben, dass man z.B. die Mathematik versteht, bei Mathematik Funktionen.

    Code
    // Bad:
    t = s + l - b;
    
    // Good:
    TotalLeaves = SmallLeaves + LargeLeaves - SmallAndLargeLeaves;

    Ich habe das EQS für Deckung genutzt, dabei habe ich über spezielle Volumes die ich selber programmiert habe das Navmesh modifiziert, so dass die Fläche eine Deckungs Navigation class hat. Über ein EQS habe ich dann erreichbare Deckungspunkte in der Nähe gesucht und bewertet.


    Eine Sache die definitiv besser gelöst werden musste:

    Um zu prüfen ob eine Deckung auch Deckung gibt, um diese raus zu filtern habe ich in der Neuen Position über Traces geprüft, ob diese Position auch Deckung für den Gegnern gibt, welche die AI kennt. Es wäre wahrscheinlich besser irgendwie Deckungspunkte zu setzen (oder zu generieren) welche diese Information enthalten ("gibt Deckung für Beschuss aus Richtung X"). Das würde die Abfrage performanter machen (z.B. Winkelvergleich oder Skalarprodukt mit Einheitsrichtungsvektoren, anstelle von Traces).

    Das wichtige hierbei ist, dass Waffe Feuern eine Task ist, die Dauerhaft läuft, bis diese beendet ist (Succeeded) oder fehlschläft (Failed)

    Deine Feuern Task benötigt nur einen Tick, d.h. dein Subtree wird sofort abgebrochen.


    Die Lösung wäre eine Waffe Feuern Task, welche läuft, bis eine andere Aufgabe ansteht. Also eher eine "Zielen und Feuern wenn Gegner Anvisiert ist, bis ich nicht mehr kann oder will"-Task ist.

    Simple Parallel wäre schon ein weg das zu machen:

    Simple Parallel, hat ein Anbindung zu einer Task Node und eine zu eine zu einem sub tree.

    Ein wenig Hintergrund: Das Konzept der Behavior Tree's sieht keine Parallele ausführung von Tree's innerhalb eines Behavior Tree's vor. Von daher solltest du es dir gut überlegen, denn zu weichst von der Theorie der Behavior Trees ab.

    Meistens sehe ich das als Warnzeichen, dass du Behavior Tree's nutzt, aber deine Überlegungen zur Implementierung eigentlich kein Behavior Tree ist. (Habe den Fehler selbst schon am Anfang gemacht)


    Der Parallel Node ist von daher ein Node der eine Main Task Ausführt, und parallel dazu einen Sub Tree. Die Main Task ist die Primäre Task, die den Node Steuert. Wenn diese Task mit einem success oder failure beendet wird, so wird entsprechend des drüber liegenden Nodes (z.B. Sequence oder Select) weiter gemacht.


    Bei mir sah es wie folgt aus:


    In diesem Fall ist es so dass es einen Combat Node gab, in dem die Main Task das Feuern und Zielen übernimmt, und parallel dazu die Bewegung lief. Wenn diese Task fehlschlägt, so kommt man durch den Select in den nächsten Node eine Art Reload Task. Diese initiert das nachladen, und es findet parallel eine Bewegung in Deckung statt. Schlägt dies fehl (keine Munition, oder kein Nachladen nötig), so kommt man in die Verfolgen Task, etc. Bei einem Success sorgt der Select dafür dass der ganze Baum neugestartet wird. D.h. wenn der Combat Node sich erfolgreich beendet (z.B.) Ziel ist eliminiert, dann wird der Baum neugestartet ein neues Ziel gesucht und die möglichen Aktionen werden abgearbeitet.

    Was ich heutzutage anders machen würde ist, dass ich als Decorator keine Perception hatte. Dies ist aber viel zu Performancehungrid und ich hätte dies als Task machen sollen, die ausgeführt wird, wenn ein neues Ziel gesucht wird.


    ist aber bei weitem nicht perfekt und ich würde einiges anders machen.

    Mir ist am Ende auch aufgefallen, dass Gegner die sich bewegen und schießen, etwas zu schwer waren, gerade in Kombination mit einem sehr fiesen Recoil Modell.

    In diesem Fall musst du noch this innerhalb der eckigen Klammern schreiben, damit das this, mit in das Lambda reingenommen wird.

    Die eckigen Klammern, sind dazu da, um Variablen die außerhalb der Lambda funktion stehen, in das Lambda rein zu bringen.


    Edit: Wie Tomar sagt, gibt es bessere Sortier Algorithmen, aber meistens lohnt es sich erst so richtig, wenn man viele Daten sortieren muss. Was vielleicht wichtig ist, bevor du sortierst ist Filtern immer gut.

    Da ich glaube dass du dich gerade mit AI beschäftigst, wäre auch das EQS system einen Blick Wert, hier werden viele Operationen auch Asynchron ausgeführt, von daher hast du somit oft weniger Last auf den Main Thread.

    Wie immer ist aber alles immer eine Sache des Use-Case, sorg Erstmal dafür dass die Dinge funktionieren, du bist ja zur Zeit am Lernen. Von daher eins nach dem anderen.

    Edit: Ich bin doof und habe nicht bis nach unten gescrollt. Sorry




    Leider musst du folgendes machen:

    1. Du machst ein UMG Widget welches nur einen Button enthält (+ Styling, Text, etc.)

    Hat auch den Vorteil, dass du den Style für jeden Button innerhalb eines Widgets managen kannst.

    Natürlich solltest du alles parametrierbar machen, was parametrierbar sein soll.


    2. Du erstellst einen EventDispatcher innerhalb des Widgets mit entsprechender Call-Signature


    Jetzt kannst du deinen Button innerhalb deines anderen UMG Widgets nutzen und hast das neue Event verfügbar

    Es gäbe Möglichkeiten über das Animation Blueprint Events in Animationen zu erfassen. Es ist jedoch meiner Meinung nach ein schlechtes Design Gameplay relevante Dinge an Animationen zu koppeln, da nicht garantiert ist, dass diese abgespielt werden (z.B. dedicated Server)


    Ich würde auch eher Timer statt delays nutzen. Delays sind übersichtlich, aber mit Timern hast bildest du besser ab was unter der Haube passiert und hast somit ein besseres Verständnis was den Programflow angeht. Bei Timern hast du auch den Vorteil dass du entsprechende Events hast, wenn dieser endet.


    Was die RPCs angeht, ist ja dein Problem einfach. Du solltest den RPC im Grunde aufrufen, wenn der Angriff initiiert wird und nicht erst wenn getroffen wird.

    Dieses Plugin ist dein Freund wenn es darum geht: https://vreue4.com/


    Hier mal wie es bei mir aussieht.

    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.

    Bei komplexen Dingen nutze ich jedoch definierte Posen (z.B. Waffengriff), bei anderen wo die Pose nicht klar ist, ist es kollisionsbasiert.

    Tomura Mit C++ hab ich eigentlich nix am Hut. In der Engine nutze ich nur die BluePrints. Das muss man doch beim Erstellen des Projektes festlegen, ob man mit BluePrints oder mit C++ arbeiten möchte. Richtig?

    Aber ich werde deinen Vorschlag mal ausprobieren. Vlt. klappt es ja.

    Ja, man muss oder eher kann es festlegen. Jedes UE4 Projekt kann aber auch nachher noch (mit etwas verständnis von der UE4 Projekt struktur) in ein C++ Projekt umgewandelt werden.


    Was bei dir passiert, ist dass bei der Konvertierung versucht wird C++ Codes zu kompilieren, welche in deinem Projekt sind.

    Die Fehlermeldung scheint ein Problem mit Funktionen aus dem HeadMountedDisplay Modul zu haben, was direkt etwas mit VR zu tun hat.

    Die Fehlermeldung scheint seinen Ursprung im Intermediate Ordner zu haben wo, objekte und generierte C++ Dateien gerne landen. Bei einem reinen Blueprint Projekt sollte da kaum was sein. Es scheint hier auch ein Binary Verzeichnis zu erstellen.


    Wenn es kein C++ Projekt wäre sollte eigentlich kein kompilieren notwending sein.


    Kannst du mal Screenshots von deinem Projektverzeichnis machen, dass man genau sieht was du hast?

    Du hast einen Fehler beim Kompilieren der C++ Codes.


    Falls es sich um ein C++ Projekt handelt würde mal vorschlagen, dass du den ganzen Intermediate Ordner löscht und die Visual Studio Projekt Dateien neu generierst:


    Das wird den Fehler nicht lösen, sorgt aber dafür, dass dort schon Mal alle Probleme eliminiert sind.

    Der Fehler selbst ist, dass sich hier einige Symbole nicht mehr auflösen lassen (hier Head Mounted Display also VR). Das kann sehr gut sein, denn UE4 ist deutlich Modularer geworden und viele Codes sind vom Engine Modul in eigene Module oder Plugins gewandert, dazu musst du vielleicht auch deine *.build.cs files etwas anpassen, dazu gehört auch das HMD zeugs.


    Edit: Anbei noch einmal eine Build.cs in der das HeadMountedDisplay Modul hinzugefügt wurde:

    Wenn dies der Fall ist lässt sich der Inhalt des Moduls über includes innerhalb deines eigenen Moduls nutzen.


    Du wirst aber falls du weitere C++ Codes hast, mehr Fehler bekommen, da sich zwischen UE4 releases gerne mal einiges ändert.


    Und bevor ich es vergesse:

    Immer eine Sicherheitskopie erstellen oder Source Control nutzen, denn ein Engine switch ist eine riesige Änderung bei der gut was kaputt gehen kann.

    Danke für eure Lösungsvorschläge. Um ein eigene Damage Logik zu schreiben müsste ich das in C++ umsetzen oder?

    Sollte auch in Blueprint gehen.

    Was genau willst du erreichen? Sagen wir mal du hast Static Meshes die irgendwie Rüstungsteile darstellen, die kaputt gehen können, würde ich z.B. anfangen einen Blueprint zu erstellen mit dem StaticMeshComponent als Parent, dieses Blueprint Programmierst du dann so, dass es Schaden nehmen kann und Leben hat.

    Diese Kannst du dann anstelle des Normalen StaticMeshComponent einsetzen, für Meshes die Schaden nehmen sollen.


    Genauso kannst du dann auch z.B. in Waffen eine entsprechende Logik erzeugen die beim Treffer (also Kollision, Trace, Overlap, oder wie auch immer du es gelöst hast) in dem Fall dass das getroffenene Component vom entsprechenden Typ ist, dann die "Schaden Nehmen" Funktion aufruft. Am besten schreibst du die Treffer logik auch so, dass auch nur die Komponenten getroffen werden können, bei denen es Sinn macht (also am besten einen eigenen Object oder Trace Channel und entsprechende Collision Settings)

    Dazu wirst du deine eigene Damage Logik schreiben müssen.

    Mit Apply Point Damage hättest du vielleicht die Möglichkeit eine Komponente im HitResult zu haben und zu verarbeiten. Aber es wäre hier wahrscheinlich sinnvoller eine eigene Apply Damage Funktion zu entwickeln und eine Komponenten die Damage abbekommen kann, oder ein Interface welches entsprechende Komponenten implementieren können falls es keinen gemeinsamen Parent gibt.

    Ja soetwas kann Sinn machen.

    Etwas abstrakter gesagt synchronisitert du nicht den Actor, sondern du hältst nur das Datenmodell (also welche Karten order gar nur wie viele Karten hat ein Spieler) synchron, während deine Actoren in jedem Client lokale repräsentationen des Datenmodells sind.

    So handhabt man z.B. gerne Special effects wie Particles und Sounds, hier müssen diese ja z.B. auf einem Dedicated Server gar nicht spawnen da gar nichts angezeigt wird, jedoch aber auf Spielerseite.

    Bis auf längere Render Zeit beim Lightmap bake sollte es keine Probleme machen (Lightmap Resolution hätte einen Einfluss)

    Aber eine richtige Map in Production Quality kann auch bei 1 ein paar Stunden benötigen wenn man in Production Quality baked.


    Eine Frage um es mal auszuschließen. Mit welcher Qualität startest du den bake? Den Fehler bekomme ich (unter anderem) auch hin und wieder wenn ich im Preview Mode bake, jedoch geht es meistens weg wenn man auf höherer Qualität den bake laufen lässt.

    Kleine Korrektur. 4.27.1 abgespeicherte Projekte lassen sich wohl in der Tat nicht öffnen. Da sagt er nur, dass das Projekt mit einer neueren Version gespeichert wurde. Aber ältere Versionen sollten halt gehen.

    Hier zu mal etwas mehr.

    Die UE5 Preview Version is Kompatibel mit UE 4.26 projekten.

    Die UE5 Release version soll jedoch dann näher an UE4.27 dran sein als an UE4.26 und mit UE4.27 Kompatibel sein.

    So zumindest die Ankündigung.


    Das ganze ist aber wie gesagt eine Preview Version, die man nicht für ernste Projekte nutzen soll. Ich habe auch so einige Bugs gehabt was Materials in Kombination mit Nanite angeht.


    C++ Projekte benötigen einiges an Arbeit, wenn man etwas tiefer eingreift (Ich habe z.B. eine Routine irgendwo gehabt welche aus Maps die World-Settings ausließt, ohne das Level wirklich zu laden oder innerhalb aller Content Pakete, also theoretisch auch solche die als Mod hinzugefügt werden nach Blueprints eines bestimmten Typs sucht) in solchen Fällen gab es einige Änderungen (die aber sinnvoll sind). Auch einige Funktionen wurden umbenannt, meistens auch um deren Bedeutung verständlicher zu machen, jedoch gibt es hier relativ klare Compiler Warnings, die sagen was zu tun ist.