Sorry sometimes I write stuff and it’s super early in the morning I’m half awake. Denny he should already have his playercontroller setup since he’s using his playercontroller class to change the Pawn type. I wasn’t talking about using the code directly with NewPlayer->GetPawn() the code you have for SetPawn is already in place. I was just copying a portion of what you need to read over that is specifically in RestartPlayer. I think this is becoming unnecessarily confusing.
If you simply set your player controller and pawn in the constructor of the gamemode class this doesn’t need to be an issue:
//Set default pawn class to our Blueprinted Character
static ConstructorHelpers::FObjectFinder<UClass> PlayerPawnBPClass(TEXT("Class'/Game/Character/0BaseCharacter/PCharacter_ST.PCharacter_ST_C'"));
if (PlayerPawnBPClass.Object != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Object;
}
static ConstructorHelpers::FObjectFinder<UBlueprint> PlayerControllerBPClass(TEXT("Blueprint'/Game/Character/0BaseCharacter/PController_ST.PController_ST'"));
if (PlayerControllerBPClass.Object != NULL)
{
PlayerControllerClass = (UClass*)PlayerControllerBPClass.Object->GeneratedClass;
}
The player controller will get spawned automatically in Login(), checked if it’s been spawned and then Initialize the player at InitNewPlayer().
APlayerController* NewPlayerController = SpawnPlayerController(FVector::ZeroVector, FRotator::ZeroRotator);
When the PostLogin() gets called, it’ll go to StartNewPlayer(), hopefully call RestartPlayer(), find a start spot and then spawn the pawn using SpawnDefaultPawnFor(). If the pawn exists then it’ll be possessed, it’ll then check if it’s null and if not then it’ll access it. It doesn’t have to be done this way but as an example of what is working by default you could look it over.
void AGameMode::RestartPlayer(AController* NewPlayer)
{
if ( NewPlayer == NULL || NewPlayer->IsPendingKillPending() )
{
return;
}
UE_LOG(LogGameMode, Verbose, TEXT("RestartPlayer %s"), (NewPlayer && NewPlayer->PlayerState) ? *NewPlayer->PlayerState->PlayerName : TEXT("Unknown"));
if (NewPlayer->PlayerState && NewPlayer->PlayerState->bOnlySpectator)
{
UE_LOG(LogGameMode, Verbose, TEXT("RestartPlayer tried to restart a spectator-only player!"));
return;
}
AActor* StartSpot = FindPlayerStart(NewPlayer);
// if a start spot wasn't found,
if (StartSpot == NULL)
{
// check for a previously assigned spot
if (NewPlayer->StartSpot != NULL)
{
StartSpot = NewPlayer->StartSpot.Get();
UE_LOG(LogGameMode, Warning, TEXT("Player start not found, using last start spot"));
}
else
{
// otherwise abort
UE_LOG(LogGameMode, Warning, TEXT("Player start not found, failed to restart player"));
return;
}
}
// try to create a pawn to use of the default class for this player
if (NewPlayer->GetPawn() == NULL && GetDefaultPawnClassForController(NewPlayer) != NULL)
{
NewPlayer->SetPawn(SpawnDefaultPawnFor(NewPlayer, StartSpot));
}
if (NewPlayer->GetPawn() == NULL)
{
NewPlayer->FailedToSpawnPawn();
}
else
{
// initialize and start it up
InitStartSpot(StartSpot, NewPlayer);
// @todo: this was related to speedhack code, which is disabled.
/*
if ( NewPlayer->GetAPlayerController() )
{
NewPlayer->GetAPlayerController()->TimeMargin = -0.1f;
}
*/
NewPlayer->Possess(NewPlayer->GetPawn());
// If the Pawn is destroyed as part of possession we have to abort
if (NewPlayer->GetPawn() == nullptr)
{
NewPlayer->FailedToSpawnPawn();
}
else
{
// set initial control rotation to player start's rotation
NewPlayer->ClientSetRotation(NewPlayer->GetPawn()->GetActorRotation(), true);
FRotator NewControllerRot = StartSpot->GetActorRotation();
NewControllerRot.Roll = 0.f;
NewPlayer->SetControlRotation( NewControllerRot );
SetPlayerDefaults(NewPlayer->GetPawn());
}
}
#if !UE_WITH_PHYSICS
if (NewPlayer->GetPawn() != NULL)
{
UCharacterMovementComponent* CharacterMovement = Cast<UCharacterMovementComponent>(NewPlayer->GetPawn()->GetMovementComponent());
if (CharacterMovement)
{
CharacterMovement->bCheatFlying = true;
CharacterMovement->SetMovementMode(MOVE_Flying);
}
}
#endif //!UE_WITH_PHYSICS
}
So as far as your setup it would probably be something like:
void AMainPlayerController::SetPawn(APawn* InPawn){
Super::SetPawn(InPawn);
if (this->GetPawn() == NULL)
{
//Failed
this->FailedToSpawnPawn();
}
else{
// initialize and start it up
this->Possess(this->GetPawn());
// If the Pawn is destroyed as part of possession we have to abort
if (this->GetPawn() == nullptr)
{
this->FailedToSpawnPawn();
}
else
{
// set initial control rotation to player start's rotation
this->ClientSetRotation(this->GetPawn()->GetActorRotation(), true);
//FRotator NewControllerRot = StartSpot->GetActorRotation();
//NewControllerRot.Roll = 0.f;
this->SetControlRotation(FRotator(0));
//SetPlayerDefaults(NewPlayer->GetPawn());
MainCorePawn = this->GetPawn();
}
}
}
I haven’t checked it yet for bugs I’ll look into it if it still doesn’t work.