x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Only one PlayerController gets spawned in Multiplayer

Hello dear community,

I am developing a little racing game with multiplayer capabilites in UE4.12. However, I noticed that, whenever I start it in the editor with more than one player, only one PlayerController is spawned, although 2 pawns are created. I can control them both, once I swap the viewport. How do I configure the game, so that for each Player that logged in, a PlayerController gets spawned? I already digged into the GameMode.cpp but it look all fine to me. Can somebody please explain this behavior and/or post a solution?

Here is the content of my ARacingGameMode.cpp:

 // Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
 
 #include "RacingGame.h"
 #include "RacingGameGameMode.h"
 #include "RacingGamePawn.h"
 #include "RacingGameGameState.h"
 #include "RacingGameHud.h"
 #include "GameFramework/GameNetworkManager.h"
 #include "Matinee/MatineeActor.h"
 
 void ARacingGameGameMode::Tick(float deltaSeconds)
 {
     Super::Tick(deltaSeconds);
     if (m_CalcBuffer > 0) {
         m_CalcBuffer -= deltaSeconds;
     }
     else{
     CalculatePlayerPositions();
     }
     
 
 
 }
 
 void ARacingGameGameMode::EndMatch()
 {
     Super::EndMatch();
     UE_LOG(LogTemp, Warning, TEXT("Match has ended."));
 
 
 }
 
 
 
 ARacingGameGameMode::ARacingGameGameMode() {
     PlayerControllerClass = ARacingGamePlayerController::StaticClass();
     GameStateClass = ARacingGameGameState::StaticClass();
     PlayerStateClass = ARacingGamePlayerState::StaticClass();
     DefaultPawnClass = ARacingGamePawn::StaticClass();
 
     static ConstructorHelpers::FClassFinder <AHUD> MyDefaultHUD(TEXT("/Game/RacingGameContent/HUD/BP_RacingGameHud"));
     HUDClass = (UClass*)MyDefaultHUD.Class;
     this->bStartPlayersAsSpectators = false;
     bDelayedStart = false;
     m_MapCheckPoints = TArray<AActor*>();
     m_SpawnPoints = TArray<AActor*>();
 
 }
 
 
 void ARacingGameGameMode::PostLogin(APlayerController* NewPlayer)
 {
     Super::PostLogin(NewPlayer);
     m_PlayerControllers.Add(Cast<ARacingGamePlayerController>(NewPlayer));
     Cast<ARacingGamePlayerState>(NewPlayer->PlayerState)->m_LastCheckpointPosition = m_MapCheckPoints[0]->GetActorLocation();
     Cast<ARacingGamePlayerState>(NewPlayer->PlayerState)->m_LastCheckpointRotation = m_MapCheckPoints[0]->GetActorRotation();
     
 }
 
 void ARacingGameGameMode::CalculatePlayerPositions()
 {
     
     m_PlayerControllers.Sort([](const ARacingGamePlayerController& A, const ARacingGamePlayerController& B) {
         
         ARacingGamePlayerState* _StateA = Cast<ARacingGamePlayerState>(A.PlayerState);
         ARacingGamePlayerState* _StateB = Cast<ARacingGamePlayerState>(B.PlayerState);
         ARacingGamePawn* _pawnA = Cast<ARacingGamePawn>(A.GetPawn());
         ARacingGamePawn* _pawnB = Cast<ARacingGamePawn>(B.GetPawn());
         
 
 
 
 
         if (A.CalcPositionScore() == B.CalcPositionScore())
         {
             FVector _distA = _StateA->m_LastCheckpointPosition - _pawnA->GetActorLocation();
             FVector _distB = _StateB->m_LastCheckpointPosition - _pawnB->GetActorLocation();
             if (_distA.Size() > _distB.Size())
             {
                 return true;
             }
             else if (_distA.Size() < _distB.Size())
             {
                 return false;
             }
 
         }
 
         if (A.CalcPositionScore() > B.CalcPositionScore()) {
             return true;
         }
 
         else {
 
             return false;
         }
     });
     
     uint8 _index = 0;
     for (ARacingGamePlayerController* _controller : m_PlayerControllers) {
 
         Cast<ARacingGamePlayerState>(_controller->PlayerState)->m_PlayerPosition = _index+1;
         _index++;
     }
 
 
 
 }
 
 void ARacingGameGameMode::PreInitializeComponents()
 {
     Super::PreInitializeComponents();
 
     FActorSpawnParameters SpawnInfo;
     SpawnInfo.Instigator = Instigator;
     SpawnInfo.ObjectFlags |= RF_Transient;    // We never want to save game states or network managers into a map
 
                                             // Fallback to default GameState if none was specified.
     if (GameStateClass == NULL)
     {
         //UE_LOG(LogGameMode, Warning, TEXT("No GameStateClass was specified in %s (%s)"), *GetName(), *GetClass()->GetName());
         GameStateClass = ARacingGameGameState::StaticClass();
     }
 
     GameState = GetWorld()->SpawnActor<ARacingGameGameState>(GameStateClass, SpawnInfo);
     GetWorld()->GameState = GameState;
     if (GameState)
     {
         GameState->AuthorityGameMode = this;
     }
 
     // Only need NetworkManager for servers in net games
     GetWorld()->NetworkManager = GetWorldSettings()->GameNetworkManagerClass ? GetWorld()->SpawnActor<AGameNetworkManager>(GetWorldSettings()->GameNetworkManagerClass, SpawnInfo) : NULL;
 
     InitGameState();
 }
 
 
 void ARacingGameGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
 {
     UWorld* World = GetWorld();
     
     // save Options for future use
     OptionsString = Options;
 
     UClass* const SessionClass = GetGameSessionClass();
     FActorSpawnParameters SpawnInfo;
     SpawnInfo.Instigator = Instigator;
     SpawnInfo.ObjectFlags |= RF_Transient;    // We never want to save game sessions into a map
     GameSession = World->SpawnActor<AGameSession>(SessionClass, SpawnInfo);
     GameSession->InitOptions(Options);
     GameSession->MaxPlayers = 2;
 
     
 
 
     if (GetNetMode() != NM_Standalone)
     {
         FOnlineSessionSettings* SessionSettings = NULL;
         IOnlineSessionPtr SessionInt = Online::GetSessionInterface(World);
         if (SessionInt.IsValid())
         {
             SessionSettings = SessionInt->GetSessionSettings(GameSession->SessionName);
         }
 
         // Attempt to login, returning true means an async login is in flight
         if (!SessionSettings && !GameSession->ProcessAutoLogin())
         {
             GameSession->RegisterServer();
         }
     }
 
     for (TActorIterator<APlayerStart> ActorItr(GetWorld()); ActorItr; ++ActorItr)
     {
         // Same as with the Object Iterator, access the subclass instance with the * or -> operators.
         m_SpawnPoints.Add(*ActorItr);
     }
     
     for (TActorIterator<ARacingGameCheckpoint> ActorItr(GetWorld()); ActorItr; ++ActorItr)
     {
         // Same as with the Object Iterator, access the subclass instance with the * or -> operators.
         m_MapCheckPoints.Add(*ActorItr);
     }
 
 
     SetMatchState(MatchState::EnteringMap);
 }
 
 AActor* ARacingGameGameMode::ChoosePlayerStart_Implementation(AController* Player)
 {
     UE_LOG(LogTemp, Warning, TEXT("Choose player start executed."))
         // Choose a player start
         APlayerStart* FoundPlayerStart = NULL;
     ARacingGamePlayerController*  _PlayerController = Cast<ARacingGamePlayerController>(Player);
     UClass* PawnClass = GetDefaultPawnClassForController(_PlayerController);
     AActor* SpawnPoint = m_SpawnPoints[0];
     m_SpawnPoints.RemoveAt(0);
     return SpawnPoint;
 
 
 }
 
 void ARacingGameGameMode::StartMatch()
 {
     if (HasMatchStarted())
     {
         // Already started
         return;
     }
 
 
 
     //Let the game session override the StartMatch function, in case it wants to wait for arbitration
     if (GameSession->HandleStartMatchRequest())
     {
         UE_LOG(LogTemp, Warning, TEXT("MatchStartHandleRequest has been executed."));
         return;
     }
     UE_LOG(LogTemp, Warning, TEXT("Internal MatchState set to InProgress. (Starting Match)"));
     Cast<ARacingGameGameState>(GameState)->m_MaxPlayers = GameSession->MaxPlayers;
     Cast<ARacingGameGameState>(GameState)->m_MaxLaps = m_maxLaps;
     Cast<ARacingGameGameState>(GameState)->m_NumCheckPoints = m_MapCheckPoints.Num();
     SetMatchState(MatchState::InProgress);
 }
 
 bool ARacingGameGameMode::ReadyToStartMatch_Implementation()
 {
     UE_LOG(LogTemp, Warning, TEXT("Game session size %s"), *FString::FromInt(GameSession->MaxPlayers))
 
         // If bDelayed Start is set, wait for a manual match start
         if (bDelayedStart)
         {
             return false;
         }
 
     // By default start when we have > 0 players
     if (GetMatchState() == MatchState::WaitingToStart)
     {
         if (NumPlayers + NumBots == GameSession->MaxPlayers)
         {
             return true;
         }
     }
     return false;
 }

Product Version: UE 4.12
Tags:
more ▼

asked Jul 05 '16 at 12:50 PM in C++ Programming

avatar image

Nico90
68 6 7 11

avatar image Shadowriver Jul 05 '16 at 02:16 PM

It should spawn out of the box, maybe PostLogin is not called? Also to be sure check if in logs something shows up, go Window->Developer Tools->Output Log.

avatar image Nico90 Jul 05 '16 at 04:05 PM

Hello Shadowriver, and thank you for your quick response. Post Login gets called as expected, the Log doesn't show anything suspicious as well :(.

avatar image Taigha Oct 02 '17 at 03:06 AM

Did this issue ever get resolved? I am seeing the same thing with multiplayer in the Editor - One PlayerController and multiple Characters.

avatar image Redemp Nov 11 '18 at 12:29 PM

I have the same problem and I can't figure out why. Did you find it ?

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question