Interaktion, richtig machen.

  • Hallo zusammen!


    Ich verwende noch ein primitives Interaktionsmenü und stelle nun fest, dass es im Multiplayer zu gehörigen Fehlern kommt.

    Etwa wenn zwei oder mehr Spieler das gleiche "Objekt" (in diesem Fall eine Nachrichtentafel) verwenden möchten.


    Hier das Bild dazu.

    Erklärung:

    Man betritt einen bestimmten Bereich (Collision Box vor der Tafel), dann kann man mit "E" die Nachrichtentafel verwenden.

    Das sollen aber mehrere Spieler gleichzeitig tun.

    Wichtig: Es soll kein allgemeines System sein (Fake) womit man denkt man würde nur dieses Objekt bedienen (in wirklichkeit ist es dann Global).





    Ich suche ein System mit dem das gewünschte Objekt (egal was es ist, ob Auto, Haus, Tafel usw.) interagiert werden kann und zwar so das man für ein paar Sekunden die gewünschte Taste gedrückt halten muss!

    Noch dazu, soll es unabhängig von anderen Spielern laufen (sofern es das zulässt).

    Es geht mehr darum das eventuell bis zu 10 Spieler gleichzeitig das verwenden können, mehr wäre eher unrealistisch.


    Alles auf dem Dedicated Server + Multiplayer.



    Leider konnte ich nichts dazu finden, denn irgendwie benutzen fast alle dieses "On Component Begin Overlap".

    Das Problem dabei ist, wenn man in der Collision Box ist, kann es manchmal sein das man nicht interagieren kann, obwohl man drinnen steht (alleine).

    Also dieses "BeginOverlap" ist recht fehleranfällig.


    Danke für eure Antworten!

    ----

    EDIT:
    Wie kann man denn globalen Namen eines "Action Mappings" auslesen?

    Wenn ich Input "E" zum Interagieren verwende (dazu ein Action Mapping erstellt habe), möchte ich gerne den Input Knopf auslesen und nicht manuell bestimmten.


    Falls man in den Optionen E umstellt, soll es auch richtig im Spiel ausgelesen werden.

    Wie macht man das?



    Ich will den Input Key Namen von "InputAction Handwerk" (E) erfahren, wie macht man das?

    Das führt bei mir zu fehlern.

    • Offizieller Beitrag

    Wenn ich richtig verstehe:


    zb.: 5 Leute treffen sich irgend wo und jeder muss in einem bestimmten Bereich die Taste E drücken und dann passiert etwas ?


    Rein von der Logik:


    1.Erstmal abfragen wie viele Personen stehen überhaupt in der der Trigger Box (zb 5)

    bzw zähle einfach hoch wenn Leute die Box betreten und ziehe ab wenn sie die Box verlassen.

    2.Nun müssen 5 Leute die Taste E drücken wo dein ein Boolean auf True gesetzt wird. Der wo nicht auf eh gedrückt hat, könnte auch eine Meldung bekommen "bitte die Taste E drücken"

    3.Verlassen die Personen den Bereich wieder, muss der Boolean wieder auf False gesetzt werden.


  • Nicht ganz.

    Eher das die 5 Spieler gleichzeitig die regionale Nachrichtentafel verwenden können (nicht global!).

    Z.B. um dort Nachrichten auszuhängen, zu entfernen, anzufügen usw.

  • Ich versuche es mal zu verstehen.


    Wenn ich es richtig verstehe möchtest du eine Art schwarzes Brett in dein Spiel einbauen. Dann musst du nicht die Tafel auf die Player aufteilen, sondern die Nachrichten die "angeheftet" werden. Sieh es wie in der realen Welt. Jeder hat seinen eigenen Flyer den er aushängt.


    Dazu musst du, wenn ein Spieler eine Nachricht hinterlassen möchte, quasi einen virtuellen Flyer, oder auch nur Nachrichtenhalter, spawnen und diesen dann an das Brett anbringen.

  • Regional (nur diese Daten werden genutzt) und Global (ALLE Daten werden genutzt), damit meine ich folgendes Beispiel:


    Auktionshaus in einem sehr großen MMORPG.

    Um das Auktionshaus aufzurufen muss man zu einem NPC (Auktionator), der Spieler denkt, das Auktionhaus ist regional, aber in echt ist es Global.

    Also alle Auktionatoren greife auf das gleiche Auktionshaus zu.

    Das bedeutet aber leider das alle Auktionen (Transaktionen) immer abgerufen werden, um dann regional gefiltert zu werden.


    Es schaut im Spiel aus als wenn es Regional ist, es ist aber Global.




    Genau das will ich nicht.


    Sondern das alles NUR Regional bleibt und nicht Global gespeichert/abgerufen wird!


    In dem oberen Beispiel mit dem Auktionshaus.

    Jeder Auktionator hat sein eigenes Auktionshaus und auch nur die Transaktionen die es genau bei diesem Auktionator gibt.

    Und nein, ich will damit explizit umgehen das man filtern muss, weil das zu viel performance kostet.



    Das Auktionshaus Prinzip ist dann das Nachrichten Prinzip.



    Das Nachrichtenbrett habe ich schon gemacht und es funktioniert auch genau so wie ich es brauche.

    Nur geht es um die Interaktion.

  • Ich brauche genau so etwas wie hier in dem Spiel um die Boxen aufzumachen.


    Man hält eine gewisse Taste gedrückt und das für einen bestimmten Zeitraum, dabei sieht man eine Animation wie sich ein Balken füllt (kreisrunder Balken) und erst dann wird eine bestimmte Aktion ausgeführt.


    Externer Inhalt youtu.be
    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.

    • Offizieller Beitrag

    Das ein Begin Overlap mal nicht reagiert ist eher sehr selten. Passiert eher nur bei objekten, die wie eine Kugel geschossen werden und die fps überspringen. Egal, du kannst die Tickrate nutzen mit GetOverlappingActors. Und nein, es kostet kaum Performance. Diese Abfrage macht der Client und wenn der Client mit E Auslöst, wird auf dem Server nochmal nachgefragt, ob der wirklich mit dem Actor überlappt.


    Zum E drücken, es reicht meistens es nur vom Client Zeitlich zu steuern, anstatt es noch vom Server überprüfen zu lassen. Ich musste aber sowas auch einbauen, dass der Server Zeitlich noch überprüft, weil nur ein Spieler das Objekt aufnehmen darf. Zwecks lag usw, wäre es sonst unfair.


    Deine Infotafel willst du ja nicht global machen, also bleiben die Infos in der Infotafel. Also speicher die auch nur in dieser Infotafel. Wäre es Global, dann würden die Infos an ein Hauptserver/hauptactor geschickt, der alles davon verwaltet und überall benutzt werden kann.

  • Wenn ich OverlapActor nutze, dann kann es sein das ich danach nicht wieder OverlapActor nutzen kann, aus irgendwelchen Gründen.

    Darum die Frage ob es dafür noch ein besseres System gibt, was auch viel präziser funktioniert?



    Wie steuert man das zeitlich mit der Interaktion (E) + Animation?


    OverlapActor -> Delay (oder retriggered Delay) 2 sekunden ... und dann?


    Pressed und Released haben zwei unterschiedliche Nutzungen.


    Das gleiche für den Angriff.

    Taste länger gedrückt halten = schwerer Angriff

    Kurz drücken = leichter Angriff.


    Wie mache ich das nun und vor allem wie bekomme ich den Namen eines ActionMappings?

    • Offizieller Beitrag

    Im Prinzip gibts nur zwei Methoden:


    1.Es passiert etwas wenn man eine bestimmte Taste drückt.

    2.Es wird in einem bestimmten Zeitabstand (zb wie DJ EKI sagte) abgefragt ob etwas passiert ist.


    zb.: Du betrittst ein Bereich, ein Blueprint wird gestartet, und bei jedem Tick wird abgefragt ob die Animation schon beendet ist.


    Wurde die Animation noch nicht gestartet oder noch nichts beendet, passiert nichts.


    Der Spieler betritt den Bereich, drückt eine Taste die Animation wird abgespielt und ein Boolean auf True gesetzt.


    Der Tick erkennt nun, dass der Boolean auf True ist und es geht weiter. Du kannst auch die Tick rate anderst einstellen zb auf 2 Sekunden. Bin mir nicht sicher ob ein Tick mit einer Sekunde + ein Delay mit nochmal einer Sekunde sein muss.

  • Das mit dem LinceTrace bin ich mir nicht so sicher, weil dann müsste man ja "alles" immer "CastTo" machen.

    Da wird die Liste irgendwann unendlich lang.





    Bei mir funktioniert das mit dem gedrückt halten nicht, kann mir wer bitte zeigen wie das richtig ist?

    Egal welchen Delay ich verwende.


    Es sollte möglichst ohne Bool Variable sein, weil diese Funktion fast überall verwendet werden soll.


    Frohes Wochenende :)

    • Offizieller Beitrag

    Ich kann dir grad kein BP machen, aber ich habe mal eins kopiert, was funktioniert hatte. Da ich es mit Server abfrage gemacht habe, ist es mit ner Timeline gemacht.



    Du musst nicht mit CastTo arbeiten um nur Infos abzurufen. Dafür gibt es Interface. Es wird ein Interface erstellt, zB Info_Interface, der alle Details abliest, die für diese Interaktion notwendig ist. zB Tafelname, Actor(self), usw. Um mit deiner Infotafel zu kommunizieren, ist auch mit Interfaces möglich.

  • Für alles was Tasten und Tastenkombinationen angeht, hab ich Macros gemacht. Warum willst des nicht nutzen?

    Macros sind nur lokal und die AxisMapping sind global.
    Meinst du das damit oder etwas anderes?



    ---

    Ich kann dir grad kein BP machen, aber ich habe mal eins kopiert, was funktioniert hatte. Da ich es mit Server abfrage gemacht habe, ist es mit ner Timeline gemacht.


    Du musst nicht mit CastTo arbeiten um nur Infos abzurufen. Dafür gibt es Interface. Es wird ein Interface erstellt, zB Info_Interface, der alle Details abliest, die für diese Interaktion notwendig ist. zB Tafelname, Actor(self), usw. Um mit deiner Infotafel zu kommunizieren, ist auch mit Interfaces möglich.


    Danke dir, aber ich verstehe das immer noch nicht.

    Input -> Pressed -> Bool not "Released" -> set "Pressed" -> wie macht man das mit der zeitlichen Interaktion?

    Input -> Released -> Bool not "Pressed" -> set "Released" -> normale Interaktion (wie zu 99% aller Situationen)


    Die Timeline sind 2 Sekunden? (0-2 Sekunden.) Weil es ja immer von 0 bis 2 sekunden laufen muss?

    Nach den 2 Sekunden (geht da nicht auch Delay ODER Regtriggered Delay?) wird die gewünschte Animation und Interaktion ausgeführt.


    Retriggered Delay -> Countdown bricht bei erneutem Tastendruck ab und startet den Zähler neu : (Beispiel: 5 Sekunden, 1x Drücken -> zählt bis 5 Sekunden, wenn man nach 3 Sekunden wieder drückt, beginnt der wieder bei 0-5 Sekunden. Die alten 3-5 Sekunden werden dann gelöscht/abgebrochen.)


    Delay -> Countdown zählt immer und stapelt sich: (Beispiel: 10 Sekunden, 1x Drücken -> zählt 0-10 Sekunden, wenn man nach 5 Sekunden erneut drückt, startet man grob gesagt einen zweiten durchlauf. Der erste hat noch 5-10 Sekunden und der zweite von 0-10 Sekunden.)



    Also nimmt man am besten:

    Input -> Pressed -> Bool "Pressed" -> Retriggered Delay -> Interaktion?

    ---


    Das mit dem CastTo kann man doch überall machen.

    Wenn man ein Interface macht, muss man in "jedem" Blueprint ein Interface einfügen. Ist das nicht zu aufwändig und vor allem zu Un-Performant?


    Weil wenn das Interface irgendwo benutzt wird, wird der Inhalt des Interface an alle Blueprints geschickt die das Interface im Blueprint nutzen?!

    Oder sehe ich das falsch?





    PS: Ich finde bei Google nicht wie man bei einem Float die Stellen nach dem Komma reduzieren/limitieren kann, weiss jemand zufällig wie das geht?

    Z.B.: 1,4324234 auf 1,43 machen :)

  • Wenn man ein Interface macht, muss man in "jedem" Blueprint ein Interface einfügen. Ist das nicht zu aufwändig und vor allem zu Un-Performant?


    Weil wenn das Interface irgendwo benutzt wird, wird der Inhalt des Interface an alle Blueprints geschickt die das Interface im Blueprint nutzen?!

    Oder sehe ich das falsch?

    Aufwändig sollte das nicht sein. Einfach im Parent-Blueprint deiner Interagierbaren Blueprints einmal die Implementation packen und du musst dich um nichts mehr kümmern.

    Es ist auch nicht unperformant, eigentlich sind Interface-Calls performanter als Casts, allerdings ist dieser Unterschied so gering, dass man ihn ignorieren kann.


    Du brauchst für Interface-Calls trotzdem ein Objekt, also nein, es wird nicht an alle Objekte, die das Interface implementieren geschickt.



    PS: Ich finde bei Google nicht wie man bei einem Float die Stellen nach dem Komma reduzieren/limitieren kann, weiss jemand zufällig wie das geht?

    Z.B.: 1,4324234 auf 1,43 machen :)

    Float * 10^Nachkommastellenanzahl -> ToInt -> / 10^Nachkommastellenzahl

  • freezernick


    Was ich damit sagen wollte ist das bei jedem Interface Call jedes Blueprint angesprochen wird und man dann noch separieren muss.

    Habe auch ein Interface für meinen "Informationen" System und da ist es so das ich jede Information auch separat filtern muss, anstatt das ganze über CastTo zu machen. Bzw. ich dies gleich direkt an MyCharacter -> Informationen Variable schicke, anstatt über Interface.


    Bei einem CastTo spricht man ja nur das gewünschte "Ding" an.



    Warum gibt es eigentlich "CastTo" und "Interface" wenn das grob gesagt doch irgendwie ähnlich/identisch ist? Was davon ist veraltete Version?




    Das mit dem Float geht das nicht auch über Text, anstatt Int? bzw. mit String und da irgendwas?

  • Warum gibt es eigentlich "CastTo" und "Interface" wenn das grob gesagt doch irgendwie ähnlich/identisch ist? Was davon ist veraltete Version?

    Das sind zwei völlig unterschiedliche Dinge.


    Casting ist eine Änderung des Variablentyps. Wenn du eine Parent-Klasse hast z.B. ein Actor und ein paar Child-Klassen Actor_ChildA, Actor_ChildB und Actor_ChildB_Child dann haben diese Child-Klassen durch die Inheritance grundlegend die gleichen Attribute wie Actor. Alle haben die Variablen, die in Actor definiert wurden und die gleichen Funktionen. Allerdings können diese neue Funktionen & Variablen haben.


    Aber weil alle die Membervariablen und Funktionen der Actor-Klasse haben, kann man alle als Actor-Variable speichern. Ein Actor_ChildB_Child ist genause ein Actor wie ein Actor_A. Mit einem CastTo nimmt man nur die Actor-Variable und ändert sie in eine Actor_B Variable (als Beispiel). Erst dann kann man auf die Variablen zugreifen, die in Actor_B definiert wurden.



    Interfaces hingegen erlauben es durch die Implementation der vordefinierten Funktionssignaturen auch nicht miteinander verwandte Klassen in einen Variablentyp zu packen, da ja alle Klassen, die das Interface implementieren diese Funktionen haben.


    Wenn du jetzt z.B. eine Blueprintklasse für deine Interactables und alle Objekte, mit denen man Interagieren kann, davon abstammen, dann ist ein CastTo auch legitim. (Solange du zur Parent-Klasse castest :P)



    Aber sowohl bei einem Cast als auch einem Interface-Call brauchst du ein Objekt und nur das spricht man an, deshalb weiß ich nicht, was du damit meinst, jedes Blueprint würde angesprochen und man müsse separieren.


    Es gibt auch ein Float to Text, wo man auch die Anzahl der Nachkommastellen festlegen kann.

    https://docs.unrealengine.com/…t/ToText_float/index.html