So, I’m having a lot of fun trying to get 4 player single view multiplayer working with UE4 4.0.2
No idea if there is a “correct” way to do it. I’ve tried a bunch of different ways that haven’t worked yet.
My current attempt (which I had working momentarily in Preview mode but has since stopped working)…
Override the GameMode, and create 4 players in the BeginPlay() using:
// Get a reference to my shared camera actor..
AActor *cameraActor = FindActorByName(GetWorld(), TEXT("GameCamera"));
// init the default player
InitPlayer(0, GEngine->GetGamePlayer(GEngine->GameViewport, 0), cameraActor);
// init 3 NEW players (creating their PAWN also)
InitPlayer(1, GEngine->GameViewport->CreatePlayer(1, err, false), cameraActor);
InitPlayer(2, GEngine->GameViewport->CreatePlayer(2, err, false), cameraActor);
InitPlayer(3, GEngine->GameViewport->CreatePlayer(3, err, false), cameraActor);
Inside InitPlayer I move the pawn to one of 4 preset locations so it doesn’t conflict with the spawn position of the next pawn (since there doesn’t seem to be any way to tell CreatePlayer where to spawn the pawn. I also SetViewTarget on the 4 player controllers to the same camera.
APlayerController *controller = player->PlayerController;
if (controller)
{
if (controller->GetPawn())
{
FTransform tx = m_playerStarts[playerIdx];
FVector pos = tx.GetTranslation();
tx.SetTranslation(pos + FVector(0, 0, 300.0f));
controller->GetPawn()->SetActorTransform(tx);
}
controller->SetViewTarget(camera);
ASAPlayerState *playerState = (ASAPlayerState*)controller->PlayerState;
playerState->PlayerIndex = player->ControllerId;
}
This works perfectly for 3 players in preview mode. Each spawns in its preset location and each is mapped to a different controller. Eventually I’d like to have support for AI characters if there are less than 4 gamepads present, but I’ll cross that bridge later.
I’ve had this working for 4 players, but somehow I’ve broken it and the screen goes black (0,0 canvas size or something) if I CreatePlayer on the 4th player. No idea why yet.
There is also a problem with the PlayerHUDs. Only player #1’s HUD gets its DrawHUD() called - possibly some artifact of how the SetViewTarget are all done to the one camera. I’ve worked around this currently by having the PlayerHUD find the other playerHUD objects and call their draw manually.
A bigger problem is that this all blows up in StandAlone mode because the Engine is creating the player pawns/controllers automatically inside LoadMap, which doesn’t seem to get called for Preview mode and happens AFTER BeginPlay… so it ends up spawning another copy of all the players. But if I tried to take advantage of this, then it wouldn’t work in Preview mode since the player spawns would never get created.
The whole approach seems very hacky.
There are Auto-possess enums on PAWNS but they don’t cause a player & playerController to be created, so not sure how useful they are.
There are the Player_Start nodes, but they also don’t seem to create a second player/playercontroller.
There don’t seem to be any examples or templates that ever try to tackle local multiplayer so I’m not really sure if I’m on the right track yet.
I’ll keep posting to this thread if I make any progress.
EDIT
Forgot to mention, I’ve overriden the GameViewportClient to disable Splitscreen for that view. This seems to work ok.
void USAGameViewportClient::UpdateActiveSplitscreenType()
{
ActiveSplitscreenType = eSST_NONE;
}