Hi everyone! Hoping someone has faced this before and can assist. I’ve been banging my head on this for a minute and I can’t seem to find any answers online. I have been working on adding features to the ShooterGame. I recently updated it to 4.17.2 and before that I followed the wiki and added the 3rd person functionality as well as created a genji dash function in C++ myself by following the pattern outlined in the wiki that added 3rd person functionality. I really like the high quality code base but I’m stuck on my next step.
I see many spots in the ShooterGame code where it references split screen functionality. My hunch is that it’s there but disabled, has anyone been able to get it working? Any help is appreciated. I have been trying to trace the functionality for a while but I haven’t been successful.
Areas where split screen is referenced are:
UShooterGameInstance::OnPreLoadMap
UShooterGameInstance::BeginWelcomeScreenState
UShooterGameInstance::BeginPlayingState
UShooterGameInstance::EndPlayingState
UShooterGameInstance::OnJoinSessionComplete
UShooterGameInstance::OnCreatePresenceSessionComplete
UShooterGameInstance::RemoveSplitScreenPlayers
UShooterGameInstance::Init
void UShooterGameInstance::OnPreLoadMap(const FString& MapName)
{
if (bPendingEnableSplitscreen)
{
// Allow splitscreen
GetGameViewportClient()->SetDisableSplitscreenOverride(true);
bPendingEnableSplitscreen = false;
}
}
void UShooterGameInstance::BeginWelcomeScreenState()
{
//this must come before split screen player removal so that the OSS sets all players to not using online features.
SetOnlineMode(EOnlineMode::Offline);
// Remove any possible splitscren players
RemoveSplitScreenPlayers();
LoadFrontEndMap(WelcomeScreenMap);
ULocalPlayer* const LocalPlayer = GetFirstGamePlayer();
LocalPlayer->SetCachedUniqueNetId(nullptr);
check(!WelcomeMenuUI.IsValid());
WelcomeMenuUI = MakeShareable(new FShooterWelcomeMenu);
WelcomeMenuUI->Construct(this);
WelcomeMenuUI->AddToGameViewport();
// Disallow splitscreen (we will allow while in the playing state)
GetGameViewportClient()->SetDisableSplitscreenOverride(true);
}
void UShooterGameInstance::BeginPlayingState()
{
bPendingEnableSplitscreen = true;
// Set presence for playing in a map
SetPresenceForLocalPlayers(FString(TEXT("In Game")), FVariantData(FString(TEXT("InGame"))));
// Make sure viewport has focus
FSlateApplication::Get().SetAllUserFocusToGameViewport();
}
void UShooterGameInstance::EndPlayingState()
{
// Disallow splitscreen
GetGameViewportClient()->SetDisableSplitscreenOverride(true);
// Clear the players' presence information
SetPresenceForLocalPlayers(FString(TEXT("In Menu")), FVariantData(FString(TEXT("OnMenu"))));
UWorld* const World = GetWorld();
AShooterGameState* const GameState = World != NULL ? World->GetGameState<AShooterGameState>() : NULL;
if (GameState)
{
// Send round end events for local players
for (int i = 0; i < LocalPlayers.Num(); ++i)
{
auto ShooterPC = Cast<AShooterPlayerController>(LocalPlayers[i]->PlayerController);
if (ShooterPC)
{
// Assuming you can't win if you quit early
ShooterPC->ClientSendRoundEndEvent(false, GameState->ElapsedTime);
}
}
// Give the game state a chance to cleanup first
GameState->RequestFinishAndExitToMainMenu();
}
else
{
// If there is no game state, make sure the session is in a good state
CleanupSessionOnReturnToMenu();
}
}
/** Callback which is intended to be called upon finding sessions */
void UShooterGameInstance::OnJoinSessionComplete(EOnJoinSessionCompleteResult::Type Result)
{
// unhook the delegate
AShooterGameSession* const GameSession = GetGameSession();
if (GameSession)
{
GameSession->OnJoinSessionComplete().Remove(OnJoinSessionCompleteDelegateHandle);
}
// Add the splitscreen player if one exists
if (Result == EOnJoinSessionCompleteResult::Success && LocalPlayers.Num() > 1)
{
auto Sessions = Online::GetSessionInterface();
if (Sessions.IsValid() && LocalPlayers[1]->GetPreferredUniqueNetId().IsValid())
{
Sessions->RegisterLocalPlayer(*LocalPlayers[1]->GetPreferredUniqueNetId(), GameSessionName,
FOnRegisterLocalPlayerCompleteDelegate::CreateUObject(this, &UShooterGameInstance::OnRegisterJoiningLocalPlayerComplete));
}
}
else
{
// We either failed or there is only a single local user
FinishJoinSession(Result);
}
}
/** Callback which is intended to be called upon session creation */
void UShooterGameInstance::OnCreatePresenceSessionComplete(FName SessionName, bool bWasSuccessful)
{
AShooterGameSession* const GameSession = GetGameSession();
if (GameSession)
{
GameSession->OnCreatePresenceSessionComplete().Remove(OnCreatePresenceSessionCompleteDelegateHandle);
// Add the splitscreen player if one exists
if (bWasSuccessful && LocalPlayers.Num() > 1)
{
auto Sessions = Online::GetSessionInterface();
if (Sessions.IsValid() && LocalPlayers[1]->GetPreferredUniqueNetId().IsValid())
{
Sessions->RegisterLocalPlayer(*LocalPlayers[1]->GetPreferredUniqueNetId(), GameSessionName,
FOnRegisterLocalPlayerCompleteDelegate::CreateUObject(this, &UShooterGameInstance::OnRegisterLocalPlayerComplete));
}
}
else
{
// We either failed or there is only a single local user
FinishSessionCreation(bWasSuccessful ? EOnJoinSessionCompleteResult::Success : EOnJoinSessionCompleteResult::UnknownError);
}
}
}
void UShooterGameInstance::RemoveSplitScreenPlayers()
{
// if we had been split screen, toss the extra players now
// remove every player, back to front, except the first one
while (LocalPlayers.Num() > 1)
{
ULocalPlayer* const PlayerToRemove = LocalPlayers.Last();
RemoveExistingLocalPlayer(PlayerToRemove);
}
}
Also inside UShooterGameInstance::Init(), bPendingEnableSplitscreen = true; is initialized. Originally it was set to false, I changed it to true. Any help is much appreciated.