I have a multiplayer game with 2 players and 2 pawns. Using print statements, I found that inputs are fired for only one of the two pawns. It seems that only one PlayerController’s SetupInputComponent function is being called. Am I missing something? Both PlayerController got constructed.
Let A := GetLocalRole() == RoleAuthority, B := IsLocallyControlled()
For the pawns, the correct distribution of instances should be
pawn_0: 1 instance where A and not B, 1 instance where not A and B, 1 instance where not A and not B
pawn_1: same as above
However, by printing in the pawn’s begin play, my pawns have the following distribution
pawn_0: 1 instance where A and not B, 2 instances where not A and B
pawn_1: 1 instance where A and not B, 2 instances where not A and not B
This means one client is locally controlling two pawns.
My code is the following
GameMode file inheriting AGameMode
ADragRaceGameMode::ADragRaceGameMode() : Super()
{
PlayerControllerClass = ADragRacePlayerController::StaticClass();
DefaultPawnClass = ADragRaceSpaceship::StaticClass();
}
void ADragRaceGameMode::PostLogin(APlayerController* NewPlayer)
{
UE_LOG(LogTemp, Warning, TEXT("gamemode post login called"));
Super::PostLogin(NewPlayer);
ADragRacePlayerController* PC = Cast<ADragRacePlayerController>(NewPlayer);
auto spawnLocation = PC->GetSpawnLocation();
PC->GetPawn()->SetActorLocationAndRotation(
FVector(spawnLocation.X + 100, spawnLocation.Y, spawnLocation.Z),
FRotator(0)
);
}
AActor* ADragRaceGameMode::ChoosePlayerStart_Implementation(AController* Player)
{
TArray<AActor*> playerStarts;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), APlayerStart::StaticClass(), playerStarts);
for (AActor* actor : playerStarts)
{
auto start = (APlayerStart*)actor;
if (start->PlayerStartTag != TEXT("Taken"))
{
start->PlayerStartTag = TEXT("Taken");
return start;
}
}
return nullptr;
}
PlayerController file inheriting APlayerController
ADragRacePlayerController::ADragRacePlayerController()
: Super()
{
}
void ADragRacePlayerController::BeginPlay()
{
Super::BeginPlay();
ship = Cast<ADragRaceSpaceship>(GetPawn());
}
void ADragRacePlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
UE_LOG(LogTemp, Warning, TEXT("player controller SetupInputComponent %s"), *GetFName().ToString());
InputComponent->BindAction("DragRaceBoost", IE_Pressed, this, &ADragRacePlayerController::Boost);
InputComponent->BindAction("DragRaceBoost", IE_Released, this, &ADragRacePlayerController::EndBoost);
}
void ADragRacePlayerController::Boost()
{
UE_LOG(LogTemp, Warning, TEXT("%s boost pressed"), *GetFName().ToString());
ship->Boost();
}
void ADragRacePlayerController::EndBoost()
{
UE_LOG(LogTemp, Warning, TEXT("%s end boost pressed"), *GetFName().ToString());
ship->EndBoost();
}
My Pawn is basically a subclass from APawn.
Any hints would be much appreciated.