Strange controller possession behavior when not spawning AI at start of level load

So this is some really strange stuff. When I use SpawnAIFromClass blueprint, not when the begin play happens in my level blueprint. The controller doesn’t get the pawn right away. Just about every initialization event, function, or whatever, will have a controller without a pawn.

I have a BTService and on EventRecieveActivationAI, pawn is null. When

UAISense_Sight::GenerateQueriesForListener

is called via component::OnRegister, the pawn is null as well. This causes a number of issues because our team ID is on the pawn. So I have these guys registering with team id 255.

The controller seems to get a pawn at some point in time after, maybe a frame delay or something. But this causes a ton of initialization to fail.

Repro steps are to jump into a level and bind a key to spawn an AI. In the controller’s being play, get the controlled pawn and it will be null. To check the working case, replace the key press event with a beginplay event and the controlled pawn will not be null.

Hey Troy,

In UE4 Actor’s BeginPlay is called when it’s spawned, and the game is already “running”. If you need to do pawn-related controller initialization override AController::Possess.

Cheers,

–mieszko

Ok, so what you are saying is that AI, that are spawned on level start, will have a possess->beginplay call order. AI spawned after that will have that order reverse because the game is currently playing. That’s fine. But does the level blueprint’s beginplay get called before or after game is “running”. Because if I spawn AI off the level blueprint’s beginplay event, I get possess->beginplay order, which is the opposite of what you are saying should happen.

Also, how is EventRecieveActivationAI supposed to work then? If you spawn AI after the game is running, you will get EventRecieveActivationAI->Possess. EventRecieveActivationAI has a controller and pawn output, which that pawn output is useless in most cases according to the initialization order currently in there.

Lastly, the perception system has me scratching my head. There are a couple of weird things. First, I would assume the perception component should live on the controller. The controller is where the BT, Services, Nodes, BB all live.

But when the component gets registered with its actor. It gathers stimuli sources that are in the perception system via GenerateQueriesForListener. If the comp is on the controller, then it will not have a GenericTeamId if the pawn is what implements that interface.

Why have the GenericTeamId on the Pawn? You might ask. Well, pawns are the only actors that are auto registered as stimuli sources by the perception system. So they need to know their team ids.

To add to the confusion, the GenericTeamId was written in a way, that it could be put on any actor (a very good thing), but the perception system clearly wants it done specific ways depending on what code path its currently running.

The reason for the long post, is that I keep having to move the team id from the controller to the pawn, now probably back to the controller. I keep telling our guys that our basic AI duder is ready, then he is not, then he is. And if I keep having to make these team Id changes. I got to get our weapon guys to redo some takedamage type work so the weapons damage the right factions :slight_smile:

So, if we are using the perception system. what is the right way to handle the team id situation? Why does there seem to be weird edge cases with level begin play with spawning and possession?

I’ve never used BeginPlay in controllers so I’ve never run into this issue. It definitely shouldn’t be inconsistent, though.

I suggest using just Possess unless you’re going to have pawn-less AI controllers in your game as well.

Similarly, event ReceiveActivationAI gets called as a result of triggering behavior tree run on your pawn-less controller. If you wait until you have a pawn everything will be fine.

Regarding registering with perception system you can mark perception component as not auto-registering and register it once your AI gets a pawn.

Oh, that’s right. I have control over the initialization of the BT. Some reason I thought it was in a component or something. Damnit.

Ok about the perception system, but you still think having the Team ID on the pawn is the right way to go about it. Correct?

Yeah, team ID on pawn is the way to go. We just usually don’t place AI on the map, we spawn them instead, that’s why we haven’t run into that issue yet. Will have to fix that.

Cool, makes sense. EQS is neat btw. Doing simple threat picking with it. Overrode a generator. Kinda want to override a scorer too. But bad things can be done with that:)

Cool. Let me know if you run into issues or have questions :smiley: