Controller not detecting controlled Pawn when spawned at Runtime

For some reason when I spawn an AI with the node “SpawnAIFromClass”, it creates the actor fine, including the AI Controller, although it fails to recognise what class the spawned actor is.

The above image is in my controller class Cont_VehiclePawn

I initially thought the casting success check to be irrelevant and was planning on deleting the branch, as the controller will only ever control actors either of or inheriting from the class BP_WhVeh_Pawn.

The casting succeeds 100% of the time when the actor is placed in the world, however casting fails every time the actor is spawned through Blueprints.
I have attempted to work around this using Get Parent Actor instead of Get Controlled Pawn, but casting still fails.

I have tried adding the node SpawnDefaultController after the SpawnAIFromClass node (this part is in my level blueprint) but that doesn’t affect anything, and I didn’t expect it to, as whenever I spawn the actor, I get the print-message “Failed to cast to BP_WhVeh_Pawn” as seen in the above image, which proves that the controller is being spawned.

It seems like the controller is being spawned and attached to the Pawn, as shown from the outliner in the editor, but the controller isn’t being assigned to the Pawn, as it is getting a null result from the GetControlledPawn node.

What’s gone wrong?

Okay I think I’ve figured it out.

My AI class BP_WhVeh_Pawn doesn’t inherit from Pawn, it’s based on the WheeledVehicle class.

I now don’t understand why editor-placed actors of this class are controlled correctly.
I need an alternative to GetControlledPawn that will work correctly.

I would delete this whole question but my answer may help someone else working with AI Controllers, Behaviour Trees and the like in regards to the WheeledVehicle.

Where I am setting the value of WhVehPawn in my controller in the above image, I do that in the actor class itself, as shown below.

The premise is exactly the same as what I was doing in my controller class, only I’m doing it from my Wheeled Vehicle actor class instead.

Something that I had to do to fix the Behaviour Tree not running as well this time was essentially adding a delay to my RunBehaviourTree node in the controller, as it was trying to run the behaviour tree before being assigned an actor to control (I assume).

My StartTick event opens a gate attached to the Controller’s tick function, from my gate I have a sequence, Then 0 goes to a DoOnce to the RunBehaviourTree node, Then 1 does the default tick functions such as updating throttle and steering for WhVehPawn.

I am very happy right now.

Omg thank you so much, This is exactly the problem i was facing and I was cracking my head trying to figure it out !! THANK YOUUUU

That helped me with exactly the same problem (in my case I was trying adapt an AI Controller to the ALS character, and placing it in world worked, but spawning didn’t (in terms of getting the controlled pawn). I’m still not sure WHY it works this way, and why spawning changes the behaviour. Still, it saved me a headache.

I know this is an old problem but it still exists in UE4.26.
After loading a streaming level+character through blueprint, the character’s controller won’t immediately have its references set up.
That means the “Get Controlled Pawn” method returns null until ~1 second into the game (put a delay on your “BeginPlay” to test this).
Something in the background sets it after that, but I can’t say what.

:exclamation:Instead, you can use the controller’s instigator (“Get Instigator” node), which should immediately point towards whatever class is using that controller.:exclamation:

Cast it or access it through an interface message and you can get whatever data you need from it.
I assume during the level set up the loaded static entities (characters placed in the editor) first spawn controllers, which then in turn possess the characters.
Why does it take ~1 second and isn’t done before BeginPlay? No idea. Probably some internal setup hierarchy shenanigans. But apparently that’s how it is.