Beiträge von Tomura

    Danke für eure Antworten.


    Janinus habe jetzt eine billige Alternative gefunden: über "Select Object", darin kann man Grafiken auswählen.

    https://docs.unrealengine.com/…s/SelectObject/index.html

    EDIT: Mist, ich sehe gerade da kann man nur 2 auswählen :(

    Über den allgemeinen Select Block solltest du eigentlich so viele Outputs bekommen wie dein Enum Einträge hat. Einfach aus dem input wo das ganze rein soll einen Pfad rausziehen und einfach "Select" auswählen (ohne Object oder so)

    Dann sollte ein Select Block erscheinen der keinen typen als input hat. Dort schliest du dann einen Pfad von Typ deines Enums an und es sollten dann entsprechende zusätzliche inputs erscheinen.


    https://docs.unrealengine.com/…ilities/Select/index.html

    Also was du willst gibt es so nicht direkt. Also müsstest du dies in eine Funktion packen.

    Entweder kommt dies A) In das BP was deine Quests Managed. B) In eine Blueprint Function Libary.


    An sich glaube ich aber dass dein Ansatz allgemein nicht sehr ideal ist:

    Auch wenn es blöd ist, dass du dein Quest System Ändern müsstest folgender Vorschlag:


    Du nutzt Objekt Orientierte Programmierung mal voll aus:

    Statt eines Structs sollten deine Quests Objects sein. D.h. Du erstellst zuerst eine Blueprint Klasse basierend auf dem Typ Object (oder Actor, falls du Replication benötgist). Dieser fügst du entsprechende Eigenschaften (Variablen) hinzu, wie z.B. das Icon, Quest Titel, Quest Text, etc. Dort kannst du auch das Verhalten programmieren was jede Quest hat oder entsprechende Schnittstellenfunktionen, falls nötig.

    Dies ist deine Basis Klasse für alle Quests.


    Nun erstellst du von dieser Blueprint Klasse neue Child Klasses. Diese benennst du nach deinen Quest Typen. Dort kannst du dann schon das entsprechende Icon Setzen. Auch hier kannst du die Logik die jede Quest des Unter-Typs sich teilt, programmieren. Eine Transport Quest z.B. hat ja durchaus gemeinsamkeiten, das hilft dir dass du ensprechenden Code nur an einer Stelle ändern musst.


    Wenn nun eine Quest Instanz erzeugen willst. Dann erzeugst du einfach ein Object vom Typ des Quests über "Construct Object From Class" und setzt nur noch Titel und Beschreibung. Da das Icon auch eine Eigenschaft der Quest ist, kannst du diese natürlich auch pro Instanz ändern.


    Wo ist der Vorteil?

    Die Logik der Quest ist in dem Typ des Quests enthalten, damit kannst du woanders Logik entfernen und dir mehr Übersicht schaffen.

    Das System arbeitet über Objekte, d.h. rein logisch sind alle variablen die auf die Quest Zeigen, zeiger auf die Quest. D.h. ein "==" bedeutet "ist es die selbe Quest" während ein "==" bei einem struct fragt ob es "die gleiche Quest" ist.

    Du hast dadurch auch viel Modularität und wenig Code Duplikation, was dir den Wartungs aufwand verringert, dadurch dass du nur einmal Programmieren musst. Damit sind verbesserungen gleich auch auf alle unter Klassen verteilt.

    Erweitern des Systems geht einfach durch erstellen eines neuen Kindes. Entfernen geht durch löschen des entprechenden Quest BP.


    Wahrscheinlich wird das etwas Arbeit für dich sein, weil ich glaube dass du dich etwas einarbeiten müsstest in OOP und die denkweise, aber ich glaube dass es sich lohnen würde.

    Ich habe jetzt den Ansatz von Tomura fertig umgesetzt, funktioniert tadellos und ich hab noch was gelernt dabei. Ich wusste gar nicht, dass man vom allseits beliebten Viewport erben und sowas damit anstellen kann. Geschweige denn von den abgefahrenen Delegates, die im ShooterGameInstance verwendet werden. Danke vielmals, für die interessanten Ansätze, das mit dem Post Process schaue ich mir auf jeden Fall auch mal an, das klingt interessant.

    Ja man kann die recht viele Engine Klassen vererben, was ich z.B. gemacht habe um bei Travel/Network failures entsprechende Nachrichten im GUI anzuzeigen, etc.

    Ich weiß leider nicht ob das in Blueprint möglich ist.

    Ich musste C++ dafür nutzen.


    Für normale Map Travels muss der Loading Screen über ein extra LoadingScreen Modul gezeigt werden. Dieses Modul wird beim Laden nicht blockiert.


    Bei einem Seamless Map Travel (z.B. server wechselt die map ohne Spieler zu kicken) muss dann aber über ein Slate/UMG Widget gearbeitet werden. In meinem Fall war es ein Slate Widget, damit sich das Loading Screen Modul und meine Viewport Klasse das gleiche Widget Teilen.


    Genaueres kannst du sehen, wenn du den Quellcode von dem ShooterGame example anschaust. Dazu musst du aber gutes C++ und UE4 Architektur Verständnis haben.

    Hier mal kein Kleiner Guide:


    Ausgehend davon dass du folgendes schon hast:

    Ein Mesh bei dem du über Materials verschiedene farben zugeweisen hast mit fertiger UVW Map.


    Dann erstellst du dir im UV Editor über den New Button ein neues Bild:


    Dann fügst du im Shader Editor jedem deiner Color Materials dieses neue Bild hinzu. Dies ist nötig damit der Baker weiß in welches Bild er schreiben muss.


    Dann musst du noch im Rendering Tab folgendes machen:



    Du stellst du Engine von Evee auf Cycles um. Im Tab Bake musst du dann den BakeType auf Diffuse stellen und bei Influence dafür sorgen dass nur "Color" markiert ist (die anderen beiden sorgen, dafür dass diffuse lighting mit gebaked wird, was du nicht willst). Dann wählst du dein Objekt im Object Mode aus und Drückst auf Bake.

    Wenn du dann in den UV Editor gehst solltest du sehen dass deine Textur die du erstellt hast nun mit den Farben gebaked ist.



    Du siehst hier auch dass das ganze etwas übersteht. Das kannst du mit "Margin" verändern, du solltest aber immer ein wenig überstehen lassen, damit etwas Sicherheit ist, bei den MipMaps die später von der Engine generiert werden.

    Feal :


    NOpen und NOpenGL sing wahrscheinlich Normal Map formate. In Unreal Engine wirst du wahrscheinlich die NOpen nutzen müssen, da in UE4 im vergleich zum Open GL Standard der Grün-Kanal (Y) Invertiert ist. (Hier geht es nur um konventionen/standards und nicht darum ob jetzt DirectX oder OpenGL genutzt wird.)


    Du kannst aber auch in der Unreal Engine dies manipulieren:

    Daher ist es eigentlich egal welche die importierst, solange du die Einstellung in der Engine richtig setzt.


    Hier siehst du mal den Effekt. Wenn du "Flip Green Channel" falsch gesetzt hast, solltest du es daran erkennen, dass die Schattierung nicht stimmt. Einfach ausprobieren, wenn du dir nicht sicher bist.

    Feal

    Ist das eigentlich gewollt, dass du die Normal Map und die Roughness/Metallic/Occlusion maps nicht nutzt oder gibt es die gar nicht?


    Kleiner Tipp:

    Du musst nicht unbedingt ein Texture Object node erstellen. Du kannst auch direkt im Texture Sample Node die Texture angeben.

    Viele downloadbare Modelle haben einen ziemlich ähnlichen Aufbau, d.h. entweder sind Roughness, Metallic, Occlusion separate Texturen oder die Roughness, Metallic, Occlusion Map als eine Textur Abgelegt, so dass R = Rouchness, G = Metallic, B = Occlusion ist (Quixel standard) oder so dass R = Occlusion, G = Roughness, B = Metallic ist (Substance standard). D.h. ich würde auch empfehlen dir ein Base Material zu diesem Aufbau zu machen, bei dem die Texturen Parametrierbar sind. Dann kannst du mit Material instances arbeitet. Das hat zum einen den Vorteil dass Shader Compile Times geringer werden (der Shader muss nur einmal compiliert werden, statt für jedes Material) und auch in den Speicher muss nur ein Shader-Code geladen werden. (Problematisch werden Material Instances erst, wenn sie zu komplex werden, aber eigentlich nur einfache Dinge tun.)


    BTW Entferne bitte die Links zu den downloads, auch wenn das ganze kostenlos ist, ist es dennoch an eine Lizenz gebunden, die man akzeptieren muss.

    hab jetzt mal was ausprobiert. Ist das richtig? Und wie mache ich das der actor sich mit der Hand attached denn da kommt ne Fehler Meldung und ich weiß nicht was damit gemeint ist

    Der Get Motion Source for Hand ist ein Node für Magic Leap.


    Ich nehme mal an, dass das du etwas an die Hand des Skeletal Meshes deines Characters attachen willst.

    D.h. Du solltest ein "Attach to Component" nutzen, wobei Target der Actor ist, den zu fixieren willst und Parent das Skeletal Mesh deines Controllers.


    Der Socket Name sollte so heißen wie der Socket an der entsprechenden hand. Diesen erzeugst du im Skeleton des Skeletal Meshes, oder du nimmst den Namen vom Hand Bone (z.B. hand_r).

    https://docs.unrealengine.com/…Meshes/Sockets/index.html


    Jetzt kommen die Attach Rules ins Spiel. Hier kommt es darauf an was genau du willst.

    Keep World bedeutet dass, das Objekt an der Ursprünglichen Position bleibt, aber sich ab jetzt mit der Hand mitbewegt.

    Keep Relative bedeutet dass das Objekt seine Position ändern, so dass seine Relativ Position/Rotation/Scale zum neuen Parent gleich der Relativ Position/Rotation/Scale zum alten Parent ist.

    Snap To Target bedeutet dass der Ursprung des Objektes auf die Position des Sockets gelegt wird.


    Hier kommt es ganz darauf an was genau du machen willst.


    BTW

    von der Funktionalität die du beschreibst kommt aber glaube ich das hier näher an dem was du willst, als was hier irgendwie vorgeschlagen wird. Wenn man es dann schöner machen willst kann man über einen Anim Blueprint und IKs die Hände entsprechend bewegen.

    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.

    oh sorry. Ich meine in ue4 um in der map mit dem spieler zu spielen. Ich modelliere grad unter dem Landscape nullpunkt und ab einer gewissen Tiefe ist der Char einfach weg.

    von was für einer Höhe reden wir denn?

    Es gibt in den World Settings einen "Kill Z" Parameter. Falls du dich unter diesem befindest, dann kann es daran liegen. Ansonsten wüsst ich nicht, warum das ganze so ist, da du sonst kaum Infos gibts.


    BTW einfach den KillZ verringern kann man zu einem gewissen Grad machen, aber ab irgendeinen Punkt kommst du in die Gegend wo du Probleme mit der Genauigkeit der Gleitkommazahlen kommst (7 signifikante Stellen). D.h. es kann besser sein, dein Komplettes Terrain so zu verschieben, dass du weder zu hohe noch zu niedrige werte bekommst

    Ich möchte gerne eine neue Qualitätsstufe in der Charakteranimation erreichen. Doch die Herangehensweise ist mir nicht klar. Vielleicht hat von euch schon mal so etwas gemacht und kann allgemeine Tipps geben.

    Ich möchte das ein Charakter (nicht der eigene, sondern ein NPC, AI Charakter) zu einem Tisch geht und so etwas wie eine Kaffeetase oder anderes voll animiert aufnimmt und auch richtg hält. Also nicht so etwas primitives, wo der Gegenstand bei Berührung mit eine Kollisionsbox zu einem Handknochen springt. Kennt jemand Programme dafür oder kann man das in der UE4 machen. Ich stell mir das sehr schwierig vor, da ich auch kein Motion Capture System habe.

    Du solltest dir in jedem Fall Skeletal Controls anschauen. Fast jedes Moderne Spiel, was viel wert auf Animationen setzt, nutzt sowas um z.B. die Position der Hand in laufe der Animation noch einmal zu verbessern, dass z.B. das Objekt gegriffen wird. Hier sind dann aber durchaus Programmierkenntnisse gefragt.

    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.

    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.

    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).

    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.

    Mein Ziel war es einfach, die Munitionsanzeige dynamisch am Spieler anzeigen zu lassen. So wie es auch in diversen Spielen bereits zu sehen ist. Als muss es ja ne möglichkwir geben das zu machen. Ich nehme aber mal an, dass die engine dazu nicht fähig ist...


    Aber dann stelle ich mir dir Frage, wieso es überhaupt ein Widget Component gibt, welches man an einem Character befestigen kann, wenn das tiwl einfach nutzlos ist.

    Also sowas?

    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.


    Das Widget Component ist recht praktisch wenn du z.B. Interaktive UIs hast z.B. ein LCD Panel mit Menus in einem Computer Terminal oder in VR für Menüs, da diese wirklich in der Welt sein müssen und nicht auf dem Bildschirm.


    Wie gesagt, was du willst ist damit möglich. Jedoch gibt es Grenzen, z.B. indem man es im Screen Rendert, statt in der World. Oder indem man von Transparent auf Masked/Opaque umstellt, damit Screen Space Post Processing vernünftig funktioniert.

    Ich hab weitere Stunden jetzt damit rum probiert, aber keine Lösung gefunden.


    Gibt es in dieser Engine wirklich keine Möglichkeit, ein HUD am Spieler mit einem Widget-Component zu befestigen, ohne das dieses bei Bewegung bis zur Unkenntlichkeit verschwimmt? Kann doch wirklich nicht sein!..

    Nutze statt Space=World lieber Space=Screen in den Widget Component Einstellungen. Jedoch kannst du dann das Widget nicht mit Welt-Objekten verdecken.


    Das Problem ist folgendes:

    Auf Grund der Natur von Screen Space Effekten kann das Spiel keine Geschwindigkeits Vektoren generieren die mehrere Ebenen haben. Somit hast du im TAA und MotionBlur keine vernünftigen Geschwindigkeitsinformationen für Transparente Objekte wie z.B. deinem Widget im Widget Component.

    Da dein Widget auch im World-Space gerendert wird, wird dieses von Post Processing erfasst.


    Falls das keine Option ist, solltest du dir ein vernünftiges Widget Material erzeugen, was z.B. Masked oder Opaque ist. (Nie probiert, sollte aber gehen). Dann wird es besser, du kannst aber bei Masked nur noch 0 oder 100% Transparenz haben. Du wirst aber trotzdem TAA und MotionBlur Artefakte haben, falls das so ist, reduziere Motion Blur als erstes. (TAA kann man auch etwas modifizieren, ist aber komplizierter.)

    Wir sehen glaube ich wenn es draußen ist wie es in der Praxis funktioniert. Was versprochen wird klingt zur jetzigen Zeit unmöglich, aber Real-time Raytracing galt auch vor RTX als unmöglich zu der Zeit wo es rausgebracht wurde. Und klar hat das ganze bestimmt seine Grenzen und Schwächen oder auch nur einfach Hardware Anforderungen die erst mit der Zeit zum Standard werden.


    Beim Rendering steckt scheinbar unter anderem eine Technik namens "Virtual Geometry Images " hinter. Hier ist ein alter Blogpost von Brian Karis, dem Mastermind hinter Nanite bei Epic: http://graphicrants.blogspot.c…tual-geometry-images.htmlUnd hier noch ein Post der dazugehört: http://graphicrants.blogspot.com/2009/01/more-geometry.html

    Der Post ist aber über 10 Jahre alt, so lange hat aber auch seine Forschungsarbeit daran gedauert. Leider gehen einige Links zu den Papers nicht, die müsste man mal raussuchen. Wenn man es verstehen will, sollte man auch erstmals das Konzept hinter Geometry Imagesund Virtual Textures (auch bekannt als Mega Textures) verstehen.

    Hier geht es also so wie ich es verstehe um eine durchaus große Neuerung wie Geometrie abgelegt, gelesen und gerendert wird.

    Man sieht aber auch dass die Paper ziemlich alt sind, es hat sich also bestimmt noch was getan, auf Hardware aber auch Forschungsebene, was dafür sorgt, dass man jetzt eine solche Technik nutzen kann.

    Virtual Geometry Images nutzt sogar keine UVs mehr (zumindest zur Laufzeit).