Changing Player Controller during Play

Hi everyone.
I am working on a game which is mostly an FPS but at some points during the level it turns into an Isometric interactive game with fixed camera or at some other points into a driving gameplay. I guess what I should do is to separate these gameplays so I must implement different Player Controllers.

Is this the standard way to implement different game plays during execution, if no then what would it be? and if yes what is the most stable way to switch between PlayerControllers? What are the important events fired up and what happens to the pawn?

I mostly work with C++ but it is good to know about BP too,
Thanks.

Hi Sachamora,

I haven’t tried it in this specific scenario, but I would think you could simply;

  1. Create a new controller actor

GetWorld()->SpawnActor(NewPlayerController, SpawnLocation, SpawnRotation, SpawnInfo );

  1. Set the desired player to the new controller, this function will detach the old controller

NewPlayerController->SetPlayer(DesiredPlayer);

Again, that is just a quick idea to work from. It follows how the game actually creates the default controller but adapted to your needs. :slight_smile:

I hope that helps.

You’ll want to copy the APlayerState variable as well since it holds all the data replicated to others (score/health/etc). You can look at the InactivePlayerState code to see how it copies over the APlayerState as an example.

A big concern would be the replication timing of the new player controller every time you do this. It would have to come from the server, and the client might be in a state where they are calling RPCs on the old player controller after the server has switched the player over to the new one. We handle that during seamless travel, but while in game these RPCs may be rejected. Depending on what you are doing this may or may not be a bad thing.

PlayerControllers are a pretty intrinsic part of the engine and dictate things like player connectivity as well, so their destruction can have side effects.

I’m not sure if this would work, but you might try creating different components on the player controller? Like a different InputComponent for example. If the idea is just code/logical separation, this might be a more straightforward way. Not sure though.

A more specific “side effect” of the RPC issue I mention is that your player will be unable to move during the transition. The player controller dictates server calls to update your position. There could be 100-500ms lag during the switch where these updates would stop. If you hide it in a “entering vehicle transition” or something, well maybe it would work, but just be away that the RPC issue is there and should be taken seriously.