[UE4.25 + Multipayer Dedicated Server] PlayerController und MyCharacter Fragen

  • Hallo zusammen!


    Ich habe derzeit Start-Probleme im Editor (es dauert zu lange bis die Charaktäre geladen sind), der Fehler liegt nun am PlayerController... irgendwie kann der sich beim Laden nicht einig werden und irgendwann hat er das geladen und dann geht es, aber mir ist noch etwas viel schlimmeres aufgefallen.


    Alle Funktionen der Charaktäre (Laufen, Schleichen, Kämpfen usw.) sind alles im MyCharacter hinterlegt und abgespeichert.

    Nun lese ich auf der Homepage:

    https://docs.unrealengine.com/…ayerController/index.html


    "A PlayerController is the interface between the Pawn and the human player controlling it. The PlayerController essentially represents the human player's will.

    One thing to consider when setting up your PlayerController is what functionality should be in the PlayerController, and what should be in your Pawn. It is possible to handle all input in the Pawn, especially for less complex cases. However, if you have more complex needs, like multiple players on one game client, or the ability to change characters dynamically at runtime, it might be better to handle input in the PlayerController. In this case, the PlayerController decides what to do and then issues commands to the Pawn (e.g. "start crouching", "jump").

    Also, in some cases, putting input handling or other functionality into the PlayerController is necessary. The PlayerController persists throughout the game, while the Pawn can be transient. For example, in deathmatch style gameplay, you may die and respawn, so you would get a new Pawn but your PlayerController would be the same. In this example, if you kept your score on your Pawn, the score would reset, but if you kept your score on your PlayerController, it would not."


    Das bedeutet das ich bisher die Funktionen immer falsch in den MyCharacter eingebaut habe, obwohl das eigentlich in den PlayerController müsste?


    Nur zur Verständigung, das Spiel soll so ähnlich vom Multiplayer her wie World of Warcraft werden.

    Also es gibt ein/mehrere Server und der Spieler verbindet sich darauf (entsprechende Welt/en) und kann dann eben spielen.


    Das Spiel was ich mache ist extrem Complex daher müssen alle Funktionen im Multiplayer auch korrekt funktionieren.


    Könnt ihr mir dazu bitte mehr Informationen zukommen lassen wie man das "Grundgerüst" für Multiplayer richtig setzt?

    Weil ich baue derzeit immer mehr Features ein die auch super funktionieren, aber der Spielstart bereitet irgendwie Probleme, jetzt befürchte ich wenn ich am Anfang einen Fehler drin habe, das sich dieser durch das ganze Projekt zieht...



    Hier noch ein paar Bilder vom Start.

    Alles beginnt mit dem OnlineGameMode (GameMode)

    ---

    Das wird dann über ein Custom Event zum OnlinePlayerController (PlayerController) geleitet .

    ---

    Bei dem MyCharacter wird das bei EventBeginPlay -> Macro (EventBeginPlay) gestartet.

    Wobei hier das Problem liegt, der kann und will die erste Funktion nicht laden um den OnlinePlayerController zu laden (es wird nicht gespeichert und ist falsch).


    Danach werden die Handwerksrezepte geladen und noch das wichtigste (bei Extrem Wichtig) die Widgets für Ausrüstungsmenü, Inventarmenü, Charaktermenü und alle Menüs eben, dafür wird der OnlinePlayerController gebraucht.


    Wie auch immer so wie es da oben ist ist es meiner Meinung nach richtig, aber der lädt einfach nicht rein, es dauert wirklich unendlich lange obwohl ich schon alles andere abgeschaltet (abgeklemmt) habe.

  • Grundsätzlich ist der Unterschied - wie Epic auch schreibt - daß der PlayerController immer erhalten bleibt - also auch wenn der pawn vernichtet wird. Ich würde so wenig wie möglich in den Player Controller packen - weil der eben wie gesagt auch erhalten bleibt wenn der Pawn zerstört ist - das kann das Spiel durchaus entlasten. Aber wenn es Sinn macht den PlayerController zu nehmen - eben weil man etwas durchgehend haben will - dann muss man das machen.


    Bei den Problemen die du jetzt hast steht man oft vor der Frage wie man die Ladezeiten entlastet - bei dir ist es wohl nur ein Bug der den prozess aufhält und ausserdem wie du sagst nichts speichert. Das musst du vorrangig beheben.


    Die Frage der Strategie ist es ja auch ob du nicht Dinge wie Menüs und Widgets auslagern solltest - es macht evtl Sinn erst die Menüs zu laden - da kannd er Spieler schon mal ein wenig rumklicken und ist beschäftigt - und dann erst den Pawn spawnen - wenn der so überladen ist daß der lange lädt und initialisiert würdest du dadurch die Situation ggf etwas entspannen. Aber ich rate hier nur, ich habe dein Spiel und die Ladezeiten nicht debuggt und du wirst sicherlich noch ein paar Bugs fixen müssen. Wenn alles so läuft wie es soll wirst du die Ladezeiten besser beurteilen können.

  • Grundsätzlich ist der Unterschied - wie Epic auch schreibt - daß der PlayerController immer erhalten bleibt - also auch wenn der pawn vernichtet wird. Ich würde so wenig wie möglich in den Player Controller packen - weil der eben wie gesagt auch erhalten bleibt wenn der Pawn zerstört ist - das kann das Spiel durchaus entlasten. Aber wenn es Sinn macht den PlayerController zu nehmen - eben weil man etwas durchgehend haben will - dann muss man das machen.

    Dem kann ich zustimmen. Mach dir einfach Gedanken, wo es hin passt. Bei Player Input wäre es z.B. schon gut dass es im Controller ist, da das Verhalten des Inputs sich ja verändern kann je nach Status des Players. Also z.B. wenn der Player im Options Menü ist, soll er ja nicht seinen Charakter steuern. So hast du eine recht guten architektorische Zwischenstufe um im Nachhinein zusätzliche Checks einzubauen die logisch eher dem Spieler gehören, als dem Charakter.

    Generell macht es mMn sinn das was den Spieler betrifft auch im Controller zu machen und das was den Pawn betrifft im Pawn und die Schnittstellen zwischen den beiden zu einfach wie möglich zu halten. So ist, wenn du nach dem Code einer bestimmten Funktionalität suchst sehr klar wo du schauen musst.


    BTW wenn du den Player Controller benötigst, solltest du auf der Pawn Seite nicht Begin Play nutzen. Das Funktioniert nur in Ausnahmefällen. Es sollte ein OnPossessed Event geben. Dies signalisiert, dass der Pawn von einem Controller übernommen wurde. Begin Play feuert aber gleich nachdem der Pawn gespawned wurde, aber noch nicht unbedingt Possessed.

    Dein Fehler kommt wahrscheinlich daher, dass der Pawn noch gar keinen Player Controller hat. Das kannst du recht einfach rausfinden indem du in deinen Blueprint reingebuggst über Breakpoints und Watchers.

  • Das die Bewegungsfunktionen und alles im MyCharacter ist, fände ich schon am besten, weil wenn ich z.B. in die Haut eines Monsters schlüpfen mag, übernehmen ich auch dessen Steuerung und die wird anders sein (vor allem für die Animationen) als beim MyCharacter.


    Um das richtig zu verstehen.

    Pawn -> MyCharacter (Actor)?


    Ich habe noch vergessen zu schreiben das ich dies hier mit im Projekt verwende:

    Das Advanced Social System, was Chat usw. beinhaltet.

    https://www.unrealengine.com/m…ct/advanced-social-system




    ...


    BTW wenn du den Player Controller benötigst, solltest du auf der Pawn Seite nicht Begin Play nutzen. Das Funktioniert nur in Ausnahmefällen. Es sollte ein OnPossessed Event geben. Dies signalisiert, dass der Pawn von einem Controller übernommen wurde. Begin Play feuert aber gleich nachdem der Pawn gespawned wurde, aber noch nicht unbedingt Possessed.

    Dein Fehler kommt wahrscheinlich daher, dass der Pawn noch gar keinen Player Controller hat. Das kannst du recht einfach rausfinden indem du in deinen Blueprint reingebuggst über Breakpoints und Watchers.


    Ich glaube das könnte das Problem dabei sein.

    Den PlayerController brauche ich vor dem laden der ganzen Widgets (Menüs), damit diese entsprechend zugeteilt werden können.

    An der Stelle wüsste ich auch nicht wie ich die ganzen Menüs auslagern sollte, denn die werden eben zum spielen gebraucht.


    Das mit den Breakpoints habe ich überall getestet.

    Wenn ich den Breakpoint auf CastToPlayerController setzte, wird dieser sofort ausgelöst.

    Setze ich den Breakpoint auf SetPlayerController dann lädt der bis zur unendlichkeit (das Problem was ich derzeit habe).



    Gibt es eine Möglichkeit eine Art "STOP" einzubauen bei der etwas ausgeführt und dann gestoppt wird, bis etwas anderes geladen ist, damit dann wenn geladen, nach dem Stop weiter geladen wird?


    Das betrifft vor allem das Ausrüstungssystem, weshalb es da zu Verzögerungen beim Anziehen kommt.



    Vielen Dank für eure Informationen!



    PS: Könnt ihr mir eine grobe Auflistung schreiben, also von der Logik her, wie genau ein perfekter Start aussieht?

    Z.B.

    1. PlayerController -> Player ID und MyCharacter sammeln/finden/setzen.

    2. MyCharacter -> PlayerController und ID setzen.

    3. MyCharacter -> Gesundheitssystem laden.

    4. MyCharacter -> Widgets laden

    5. MyCharacter -> usw.


    Sozusagen eine Reihenfolge die auch perfekt harmoniert.

    Vor allem noch, wie erstelle ich eine Vorab Datenbank für die Spieler/Benutzer in der:

    Accountname:

    Passwort:

    Der PlayerController + MyCharacter gespeichert wird

    Diverse weitere einstellungen.


    Danke

    • Offizieller Beitrag

    Hast du mal durch das trennen der Nodes ausprobiert, wann deine Charaktere sofort geladen werden?


    Mach dir mal mit PlayerController nicht so viele Gedanken. Du hast es jetzt zwar gehört, wie die sich verhalten, aber ich finde die zb sehr verwirrend, wenn es um Multiplayer geht. Deine ganzen Werte, falls ein Spieler disconnected und wieder connected, werden sowieso von einem Server verteilt.

  • EIne gute STrategie wenn man das Laden beschleunigen will ist mit mehreren Levels zu arbeiten - dann kannst du das einfach ins Level BP hauen.


    zB. Startp Level ist lvlSplash - hier werden nur die Firmenlogos kurz runtergerattert

    --> LvlIntro - hier wird das Intro abgespielt, kann bei mir auch durch Optionen später ganz abgeschaltet bzw. Übersprungen werden.

    --> Lvl Main menu - hier ist nur das Main Menu Widget drin um ein SPiel zu laden, ein neues zu starten, Optionen einzustellen usw.

    -->LvlGame -- Hier lädt erst das eigentliche Spiel, was dann vom laden auch etwas länger dauert - das kann man im LvlMainMenu aber auch streamen um es heimlich zu laden während der Spieler noch dumm durch Buttons rumklickt.



    Es gibt viele Wege und alle führen nach Rom.

  • Um das richtig zu verstehen.

    Pawn -> MyCharacter (Actor)?

    Ja. Ein Character ist eine Art Pawn, ein Pawn ist aber nicht unbedingt ein Character (z.B. könnte ein Pawn auch ein Spectator Pawn sein).


    Ich glaube das könnte das Problem dabei sein.

    Den PlayerController brauche ich vor dem laden der ganzen Widgets (Menüs), damit diese entsprechend zugeteilt werden können.

    An der Stelle wüsste ich auch nicht wie ich die ganzen Menüs auslagern sollte, denn die werden eben zum spielen gebraucht.

    Also du solltest unbedingt mal recherchieren wie das Gameplay Framework von UE4 abläuft:

    Ganz grob gesagt:

    Ganz oben ist die GameEngine diese existiert ab dem Start des Spiels, genauso die GameInstance, diese könnt nach der Engine. Beim Start wird eine Map/World geladen, die World lebt solange wie das Level existiert. Die Welt halt einen GameMode, welcher erzeugt wird nachdem die Settings der Welt verfügbar sind. Auch wird für jeden Spieler ein PlayerController erzeugt (+ das was noch so dazugehört), basierend darauf was im GameMode eingestellt ist. Der PlayerController spawnt dann einen Pawn und wenn der Pawn fertig gespawnt ist, dann wird dieser Possessed.


    Jetzt muss man sich das mal anschauen:

    1) Controller spawnt einen Pawn

    2) Pawn ist fertig gespawnt => Pawn->BeginPlay

    3) Controller übernimmt pawn d.h. der Controller des Pawns wird gesetzt => Pawn->Possessed


    D.h. wie ich gesagt habe, nimm das Possessed Event. Es gibt hier auch keine echte Verzögerung, das das ganze normalerweise im selben Frame stattfindet.


    Folgendes:

    Der Player Controller existiert vor dem Pawn. Der Pawn wird zuerst sauber gespawned inklusive BeginPlay Event. Erst danach wird der Pawn possessed, da erst hier alles was beim Spawn passieren soll passiert ist.

    Das heißt benutze nur Begin Play für Dinge die gemacht werden sollen nachdem der Pawn gespawnt ist und nur das innere des Pawns betrifft. An diesem Punkt hat der Pawn noch kaum Infos.

    Das mit den Breakpoints habe ich überall getestet.

    Wenn ich den Breakpoint auf CastToPlayerController setzte, wird dieser sofort ausgelöst.

    Setze ich den Breakpoint auf SetPlayerController dann lädt der bis zur unendlichkeit (das Problem was ich derzeit habe).

    Dann ist es doch klar. Der Cast schlägt fehl und du kommst nicht weiter. Also ist der Input des Casts Null oder ein PlayerController mit falscher Klasse. Da du in Begin Play bist, ist der Player Controller wahrscheinlich null, da dein Pawn noch nicht Possessed wurde. Also schieb die ganze Logik in das Possessed Event.

    Gibt es eine Möglichkeit eine Art "STOP" einzubauen bei der etwas ausgeführt und dann gestoppt wird, bis etwas anderes geladen ist, damit dann wenn geladen, nach dem Stop weiter geladen wird?

    Wenn du das machen musst machst du etwas falsch. Informiere dich über die Events die es gibt und den generellen Ablauf des Gameplay Frameworks. Was du vorschlägst ist eine riesige Verschwendung von Performance.

    PS: Könnt ihr mir eine grobe Auflistung schreiben, also von der Logik her, wie genau ein perfekter Start aussieht?

    Z.B.

    Wenn du den Perfekten Start eines Levels selbst programmieren musst, machst du etwas falsch. Wie gesagt die UE4 bietet schon ein Gameplay Framework, du musst nur wissen welche Events du Implementieren musst und welche Funktionen du überladen und erweitern musst.
    Von daher, wie ich schon öfter sage. Recherchier genau wie die Unreal Engine funktioniert, das kann auch paar Wochen/Monate dauern. Am einfachsten ist es natürlich einfach den C++ Code grob anzuschauen, aber es sollte auch z.T. erklärt ein. Wüsste aber nicht wie gut Epics Doku ist.


    BTW falls du Multiplayer machst:

    Das Possessed Event läuft nur auf dem Server. D.h. du musst für Client seitige Dinge auch Client Funktion aufrufen. In vielen Fällen geht auch das Restart Event, dort ist 100% klar dass alles abgehandelt wurde, aber wenn ich mich richtig erinnere feuert es nur beim Spawn des Pawns aber nicht, falls dieser mitten in seiner Lebenszeit possessed und unpossessed wird. Man könnte ja ein Spiel so programmieren, dass Spieler andere Pawns übernehmen oder die Kontrolle abgeben, etc. dann wird natürlich kein Restart Event gefeuert, weil der Pawn ja schon "gestartet" wurde.

  • Hast du mal durch das trennen der Nodes ausprobiert, wann deine Charaktere sofort geladen werden?


    Mach dir mal mit PlayerController nicht so viele Gedanken. Du hast es jetzt zwar gehört, wie die sich verhalten, aber ich finde die zb sehr verwirrend, wenn es um Multiplayer geht. Deine ganzen Werte, falls ein Spieler disconnected und wieder connected, werden sowieso von einem Server verteilt.

    Ja Problem bleibt bestehen.

    Also muss ich da noch weiter forschen.


    Es wird auch beim Start dies hier angegeben:


    Tomura Da bin ich derzeit dabei, vielen Dank!

  • Wieso holst du da noch mal einen Controller, wenn du schon die Referenz zum Controller im Possessed Event drin hast?


    Na weil ich den PlayerController doch in einer Variable abspeichern muss!

    New Controller passt eben nicht in SetPlayerController rein.


    Anders gesagt:

    NewController ist bei mir nicht OnlinePlayerController.

    Sonder nur PlayerController, womit ich ja nichts anfangen kann, da alles wichtige in OnlinePlayerController enthalten ist.

  • Aber leider geht das auch nicht, weshalb ich wieder zum:

    EventBeginPlay -> CastToController -> Set Controller zurückgreife muss.


    Denn bei Event Possessed lädt der unendlich lange und das Spiel kann nicht gestartet werden.


    Aber leider hängt das wieder beim Laden... es ist echt schlimm :(


    Wenn ich Rüstungsteile in die Welt setze, lädt es furchtbar lange, entferne ich diese lädt der Sofort rein.

    Das ist echt unbegreiflich warum der Editor so komisch ist.

  • Geloscht


    So etwas habe ich gar nicht, also SpawnActor (MyCharacter)...


    Habe 2 "PlayerStart" gesetzt und fertig, sonst nichts.

    WorldSetting: Default Pawn Class = MyCharacter


    Ob da vielleicht der Fehler liegt das der Character zwar gespawnt wird, aber es deshalb irgendwie zu Verzögerungen kommt?


    Habe mal einen Gegencheck gemacht, siehe Bilder:

    Rot = MC = MyCharacter

    Blau = OPC = Online Player Controller (PlayerController)


    Client = lädt lange aber es funktioniert alles Fehlerfrei.

    Aber die Werte sind falsch, so gesehen gibt es nur ein PlayerController die sich beide Spieler teilen...


    ---

    Server = lädt unendlich lange und nichts funktioniert.

    Aber es wird korrekt angezeigt.



    Obwohl das Level leer ist, bis auf die Rüstungsteile, dauert es trotzdem lange.

    Gibt es eine Möglichkeit, abgesehen von BRAKE, zu sehen wo das Laden zu lange dauert, damit ich besser nachforschen kann wo da der Fehler liegt usw.

    • Offizieller Beitrag

    Ferndiagnose ist jetzt sehr schwer. Ich müsste da eher selber mich durchklicken, was ich auch machen würde, aber so kann man immer nur was erahnen, weil man kennt so ein Problem nicht.

    Dann könntest du einfach mal ein Fix up Redirector Folder machen auf dem gesamten Content. https://docs.unrealengine.com/…cs/Redirectors/index.html