Order of Operations for AIController derived classes
When you make an Unreal Engine character (based on the ACharacter
class) and it has a controller derived from the AAIController
class, calls
to the methods BeginPlay()
and OnPossess()
happen in a different sequence depending on how the character is created:
- if the character is placed in the level using the editor,
OnPossess()
is called beforeBeginPlay()
- if the character is spawned using (say)
World->SpawnActor()
thenBeginPlay()
is called beforeOnPossess()
This means if you initialize the AI blackboard in the OnPossess()
call and write values into the blackboard
on the BeginPlay()
call, this will work when the character is placed in the level but will silently fail
when the character is spawned at runtime.
It will fail because the keys have not been created in blackboard yet, and it will be silent because a call like this:
BlackboardComponent->SetValueAsObject( ... )
does not have a return value which can be tested for failure.
Other Effects
This has other effects when considering the player pawn. If you retrieve the player pawn using a line like this:
APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
in your implementation of BeginPlay()
, in the case where the character is placed in the level PlayerPawn will
be null, but if the character is spawned at runtime it will have the expected value.
So you can't handle the different call sequences by just putting all the code into OnPossess()
, because the
values it sees also depend on how the character was created.
Reference
Advanced Debugging In Unreal Engine
Feedback
Please leave any feedback about this article here