Understanding PlayerControllers as they Relate to Multiplayer

Currently, my understanding of PlayerControllers are that they are used as a persistent controller of pawns. You put the logic necessary for pawns to function in the PlayerController, especially if the pawns are destroyed and respawned during the game. My questions are:

  • Should you have multiple player controllers for pawns with different behaviors?

  • In multiplayer, is it better to have a single PlayerController that handles the client/server login logic, and then have the pawn’s contain their own logic for how they operate?

  • Basically I’m just trying to understand the best practice with PlayerControllers

For reference: I’m creating a multiplayer game where one player has the HTC Vive and another player is just on a computer. So the pawns have very different roles and behavior.

If you want different controls and behavior then probably yes use different playercontroller classes.
When you talk about handling things for the login logic, that is usually worked out between the GameInstance and GameState classes.

How this goes depends greatly on whether the client machine decides on player setup before or after joining the server.

Remember:
GameMode contains the rules and exists only on server.
Gets created each time a level is opened (maybe different with seamless travel)

GameInstance exists on each machine, and it with its variables stays alive between level changes and joining, starting, and quitting network sessions. But it does NOT talk to other machines. Does not replicate across network. Gameinstance is for the machine it lives on and no other machine can communicate with it.

GameState gets created each time a level is opened (maybe different if seamlessly) and this is where you
Keep track of things that apply to everyone generally.

PlayerStates live on the GameState and represent information about each player that doesnt necessarily involve their controls or behavior, things like score, health, etc. That you want to replicate. Also comes natively with unique ID that is consistent across all machines in the network session.
Playerstates get created new each time a level is opened (maybe different for seamless travel)

Playercontrollers live on each machine and represent the players that are using that machine.
The Server has all playercontrollers from all machines. Each client has only their own machine’s playercontrollers.
PlayerController ID 0 represents the first player on the machine that is asking for it. If you Get PlayerController 0 on another machine, it will fetch the first player that lives on THAT machine.
Playercontroller IDs of -1 represent remote players not owned by the machine that is asking about it.

Pawns may be possessed by an AI controller, a playercontroller, or nothing. It is possible to control a pawn without a controller but usually it is best ot use one especially in network multiplayer because controllers and their pawns own the connection to their corresponding replicated counterpart on the server. That is how Unreal.knows who receives the Event handling on the other end when you make a Remote Procedure Call.

Multicasts meant to affect the whole world usually work best from GameState on the server.
Client events meant to affect one Player on one machine work best from the corresponding PlayerController on the server.