I set the editor to use 2 clients (1 listen server + 1 client) and every frame for both clients is printing 4 different names MyCharacter_C_0, MyCharacter_C_1, MyCharacter_C_2, MyCharacter_C_4 (or other similar values, but always 4 entries). If you increase the number of clients the number of instanced characters increases exponentially. If i run one of the windows on the editor viewport the Scene Outliner only shows 2 instances. Why is he creating more character instances than clients?
So for example MyCharacter_C_0 is the character i’m controlling, MyCharacter_C_1 is the other player i’m seeing, and MyCharacter_C_2 and MyCharacter_C_3 are replicated copies of the character i’m controlling and the other player i’m seeing?
And should those copies execute the normal workflow? Tick, BeginPlay, etc? Because MyCharacter_C_3 crashes on Tick for not having a Controller on a call that i make to deproject mouse coordinates, the replicated copies should have a controller? If not then why does the other player replicated copy doesnt crash there?
The server has player controllers for all players, but clients only have a player controller for the local player. You should check that the player controller on a pawn is non-null AND that IsLocallyControlled() returns true before executing code intended for the local player.
Thank you very much for your help, i just have one more doubt. Is there a way to know that you are the character you are controlling? Just using IsLocallyControlled is not enough because that is only telling me if it’s being controlled by someone.
Clients will have an APlayerState for each player in the game but only one APlayerController for themselves. Servers will have an APlayerState and APlayerController for each player (human or otherwise) in the game. Listen Servers specifically will have to identify which is theirs.
The APlayerState array (PlayerArray) is on the AGameState, accessible on both client and server.
APlayerState’s owner is an APlayerController. If the owner is NULL on clients, then its not local. If the owner is not null and not IsLocalPlayerController (or IsLocalController) then its not local on the server.
Just watch out that IsLocalController isn’t used during player controller construction/destruction, because its behavior is undefined.
Sorry, I’ll add that a Pawn/Character also has a pointer to the same AController, so you can get up the chain that way as well.
And with 3 clients (1 listen server and 2 pure clients) it printed 2 characters, am i missing something?
Role != ROLE_Authority - To make sure it’s a client Controller != NULL - To check if it has a valid controller Controller->IsLocalPlayerController() - To check if it has a valid player controller PlayerState->GetOwner() != NULL - To check if the player state has a valid owner