Custom AIController called twice and GetPawn()==NULL

In my project I have a playerPawn (already in the world) and an enemyPawn which should be possessed by AI when I spawn it into the world. enemyPawn is a c++ class based on Pawn, then i created the related blueprint. The problem appears when i spawn the enemyPawn and from myAiController i try to GetPawn(). GetPawn() returns NULL also if the enemyPawn was already created. The funny thing is that for some reason the beginplay function of myAIController runs for a second time and in that case the GetPawn() is not NULL.

I think everything is set correctly :
Pawn section of enemyPawn

272981-question1.png

This is my CustomAiController derived by AAIController

In my Enemy constructor i also added this two lines

AIControllerClass = AMyAIController::StaticClass();
AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;

but i don’t think they are strictly necessary
I spawn the enemyPlayer from the gamemode (but it is the same if i spawn it everywhere else) through this instruction

AEnemy* enemy = GetWorld()->SpawnActor<AEnemy>(EnemyClass, FVector(600.0f, 0.0f, 0.0f), FRotator(.0f, .0f, .0f));

Do you have any idea why i get null the first time? and why beginPlay of MyAIController is called twice?

I also made an experiment in a new project with just a pawn, CustomAIController (that check if getPawn() is null otherwise it prints the name of the pawn) and an actor who spawns 3 pawns and I printed the result.

272986-question3.png

Can you solve this mistery???

UP UP UP UP

[48h UP] Still have this strange “problem”. I can continue to develop but i’m curious about this behavior. Hope someone has some idea!

Okay, I solved the problem in this way (maybe can help someone):

  • First of all i put the Super::BeginPlay() in in the BeginPlay() of my custom AAIController

  • Second i override the Possess function of AAIController

     void AEnemyController::Possess(APawn * InPawn)
     {
     	Super::Possess(InPawn);
     	controlledPawn = Cast<AEnemyPawn>(InPawn);
     	if (controlledPawn) {
     		//Pawn not null ***theorically you can do something here***
     		UE_LOG(LogTemp, Warning, TEXT("GetPawn() worked. Name: %s"), *controlledPawn->GetName());
     	}
     	else {
     		UE_LOG(LogTemp, Error, TEXT(" Pawn is null"));
     	}
     }
    

I understood also that Possess is called before of the controlled pawn’s beginplay() so pay attention in anycase (I solved initializing things in constructor or in SpawnActorDeferred.

Still i don’t know why BeginPlay was called twice but in some way I managed the problems.

1 Like