Lokaler Multiplayer mit gemeinsamer Kamera: Probleme mit der Bewegungsbegrenzung der Charaktere

  • Hallo,


    Ich suche etwas Hilfe!


    Rahmenbedingungen:
    Ich arbeite gerade an einem Top-Down-Shooter mit lokalem Multiplayer. Dabei können vier Spieler zusammen auf einem Bildschirm spielen und müssen gegen Monster Wellen kämpfen.


    Situation:
    Ich habe einen CameraActor geschrieben, der das Zentrum aller Charaktere fokussiert. Zusätzlich zoomt die Kamera automatisch abhängig zur Entfernung zwischen den Charakteren.


    Ziel:
    Die Charaktere können nicht aus dem Bild laufen sondern werden im Bild gehalten, damit keiner verloren geht.


    Problem:
    Ich habe folgendes System implementiert, welches wunderbar funktioniert, aber nur für den ersten Spieler. Diese Bewegungseinschränkung wird von den anderen Spielern ignoriert.





    Ich sitze schon ein Weilchen an diesem Problem und die Recherche in den offiziellen Unreal Bereichen blieb erfolglos.
    Jeder Tipp ist hilfreich!


    gruß Micha
    #FirstPost

  • Hi,


    Ich habe folgende Zeilen dem Quelltext im obrigen Beitrag ergänzt, damit das nochmal nachvollziehbarer ist, danke für den Hinweis.


    Code: .h
    ATDS_PlayerController* m_PlayerController;


    Code: .cpp
    // Called when the game starts or when spawned
    void ATDS_Character::BeginPlay()
    {
        Super::BeginPlay();    
    
    
        m_PlayerController = Cast<ATDS_PlayerController>(Controller);
    
    
    }


    Ich nutze m_PlayerController um die ProjectWorldLocationToScreen Funktion aufzurufen. Die erlaubt es mir, die WorldLocation auf den Screen zu projizieren, weil ich dort klare XY-Werte habe,
    welche ich begrenzen kann. Ich habe es vorher andersrum probiert, aber durch einen angewinkelten Kamerawinkel gibt es keine klaren XY-Grenzen und ich bekomme komische werte. Mit WorldToScreen funktioniert das
    wunderbar, leider nur für Spieler 1 bzw 0.

  • Hm, nein habe ich nicht, ich wüsste aber auch nicht wie, da die AddOnScreen Messages nur vom ersten Player geprintent werden.
    Was vielleicht noch interessant wäre zu erwähnen, ist dass ich in meiner gamemode.cpp 3x CreatePlayer aufrufe, da ja jeder character ( die bereits in der szene stehen ) einen zugewiesen bekommen.


    Alle vier Charaktere Blueprints erben ja von meiner TDS_Character.h , d.h. doch dass alle vier gleich funktionieren sollten oder?

  • Das Problem was ich sehe ist, dass du die Variable "m_PlayerController" im BeginPlay initialisierst, das Event wird beim Start des Spiels/Spawn des Characters aufgerufen, der Controller wird aber erst NACH dem Spawn injected (PlayerController->Possess), deswegen drängt sich mir der Verdacht auf, dass die Variable NULL ist.


    Versuch doch einfach mal testweise die Variable außen vor zu lassen und hohl dir den Controller in deiner Methode

  • Ich habe nun mal den Controller in der Methode geholt. Wenn ich so darüber nachdenke macht das ja auch voll Sinn. Denn die Controller 2-4 werden ja in der GameMode Created, d.h. dass
    die Charaktere die bereits in der Szene stehen zu Play Beginn keinen Controller haben, denke ich mal. Nun ja aufjedenfall passiert etwas. Die Charaktere 2-4 bewegen sich nun nach rechts unten bis
    ohne zu stoppen. Auch bei Input reagieren diese nicht, da die Bewegung wahrscheinlich überschrieben wird. Ich denke das die vier If abfragen die falschen Bedingungen haben. Was mich aber verwirr ist,
    dass der Player 1 funktioniert.

  • Darauf wollte ich hinaus (wusste nicht wie du die anderen Character erstellst).


    Ich persönlich würde die Methode eh anders gestalten, zunächst würde ich als Return Type einen Bool nehmen und in der Methode prüfen, ob die aktuelle Character Position + Input den Viewport Bound überschreitet, wenn ja "return false" wenn nicht "true" zurückgeben. In deinen Movement Methoden könntest du dann etwas machen wie:


    Code
    if ((Controller != NULL) && (Value != 0.0f) && isInBound())
  • Ich werde es direkt einmal ausprobieren.


    Was ich gerade noch festgestellt habe ist, dass Charactere 2-4 in der Zeile

    Code
    m_PlayerController->ProjectWorldLocationToScreen(GetActorLocation(), m_ScreenLocation);


    nur eine x=0, y=0 in m_ScrrenLocation stehen haben, anscheinend wird der wert in der methode nicht gesetzt.

  • Okay, habe mal folgendes gebaut:



    und habe die If in meiner Movement so erweitert wie vorgeschlagen.


    Klappt halt weiterhin beim ersten Player, nur dass er halt wenn er aus der Boundary ist nicht mehr bewegt werden kann. In der vorherigen Variante wurde er immer wieder ins Spielfeld gedrückt.
    Das Problem ist, das die ProjectWorldLocationToScreen bei den Characteren 2-4 falsche Werte ausgibt. Aber warum das so ist erschließt sich mir nicht.

  • So ich habe das Problem gelöst.


    unzwar hier:


    Code
    ATDS_PlayerController* _PlayerController = Cast<ATDS_PlayerController>(Controller);


    Ich habe anstatt den eigenen Controller zu nutzen, nur den des ersten Player:


    Code
    m_PlayerController = Cast<ATDS_PlayerController>(GetWorld()->GetFirstPlayerController());


    Darauf werden auch die Werte realistisch und die Charactere verhalten sich nun wie gewünscht.


    Danke für die Hilfe ! :)