Ai controller can never be destroyed or be garbaged collected

In this example I spawn an Ai_Controller with zero references in this level and I can neither destroy it, nor make it get garbage collected.
I have attached the test project.

https://drive.google.com/open?id=0Bzdmwe7OtDm9dVBUeGY5ZXpiWTA

Hey UE4Hobbyist,

I’m a bit confused as to why you’re spawning an instance of the controller in your level. Could you elaborate on your reasoning for this?

This same setup works fine if the controller is possessing a pawn. For example, if you create a Pawn, assign it an AI Controller, and then inside the Pawn Get AI Controller->Unpossess->Destroy (make sure the AI CON reference is assigned to Unpossess and Destroy) it will destroy it as expected.

Also, I recommend giving this a try in 4.15 to see if the same issue occurs.

Let me know if you have any further questions and let me know the results of the 4.15 test.

Have a great day

The steps described still leave an AIController in the level. This was tested with 4.15.1

Tried unpossessing and destroying inside Character’s BeginPlay

Tried it in the level blueprint

Yet, there it is, in the world outliner when I hit play:

134632-world_outliner.png

I know that this AIController belongs that specific Pawn since 1) it’s the only pawn in the level and 2) when I set the Pawn’s AI controller class to None, no rogue AIController is seen during PIE.

Is there a separate “Destroy” function that you’re referring to? DestroyActor is the only one that seems to work with the AIController as the target.

Thanks for the update. I’ve reproduced the issue and have entered a bug report, which you can track using the link below:

Have a great day

I would like to point out that Controller.cpp specifically overrides DestroyActor with this:

void AController::K2_DestroyActor()
{
	// do nothing, disallow destroying controller from Blueprints
}

So I’m not sure whether this is intended behavior or something that slipped through the cracks (given that one can unposses a controller via BP, unsure why destroy would be forbidden).

For UE4Hobbyist: a workaround would be to write your own C++ function library that takes in an AController* or AIController*, call controller->Unposses(); and controller->Destroy(); directly.

This workaround worked in my case. Thank you!
However, I wanted to point out to other readers that if you call UnPossess() directly on the ‘Controller’ pointer of your Pawn, you cannot call Destroy() on it afterwards because UnPossess() nulls the pointer.
So the solution here would be to create a pointer to the Controller object and call Destroy() on that.
Like so:

auto controllerRef = Controller;
Controller->UnPossess();
controllerRef->Destroy();

It’s ugly but it works.

Maybe Un possess is unfit for detach from AI Character!!
You Just Need ues “Detach from controller pending destroy” node, Before Destroy Ai controller.
Good luck

I’ve tried to duplicate this in blueprint, but it doesn’t seem to be working as the AI controller is still not destroyed. I’ve followed your logic on this and created an additional reference to the AIController, unpossessed the first one then used the second one for a destroy command, but it didn’t seem to work as after killing several pawns, the number of AI controllers in the world never reduced.

Trying this in 4.21.1.

The AiController can’t destroy itself “by design”, best you can do is Destroy the BrainComponent (ie, The Behavior Tree) and stop tick, which at least will clear up some resources.

In C++ you can GetWorld()->RemoveController(YourAiController); but it doesn’t work either…

So I guess AiControllers are here to stay?

You don’t have to do this. It’s done automatically for you on Unpossess.

1 Like

And yet when you unposses an ai pawn, the behavior tree keeps running unless you manually kill it. just try it. Maybe as much as it’s supposed to do it, the engine is not actually fault-proof.

If bAttachToPawn is checked in the AIController class and i destroy the pawn. the AI Controller object is still in the scene. The mentioned issue says resolved, but i could not find the resolution

This is actually the solution, due to the BP node not doing anything.

just call PawnPendingDestroy()

I made a new pawn that has no mesh or anything and is set up so the default AIController is NONE.
When I want to destroy an AI controller I spawn this baby (since it’s set to NONE it doesn’t automatically spawn an ai controller) and possess it. Then destroy this pawn and it will take the ai controller with it to the grave.

On the other hand for me destroying the pawn does destroy the AIController possessing it. I added a bit of delay before the destroy so it has time to properly possess it, just in case. No better idea.

For anyone else still running into this problem… as noted above, the DestroyActor() node in blueprints has no effect, but there are other options that are just as simple – use either one of these:

  • call the SetLifeSpan() node with a non-zero value (zero is equivalent to “indefinite” in this case), OR

  • set AutoDestroyWhenFinished to TRUE

I use one of these nodes in my AI Controller blueprint’s OnUnPossess event, as well as SetActorTickEnabled(false) in the case of SetLifeSpan() in order to stop processing Tick events immediately.

Either of these methods appears to properly remove my AI Controller instance from the world outliner (and hopefully garbage collected etc).

Hope this helps!

13 Likes

Yes using the set lifespan node works, I can see that the AI controller is deleted in the world outliner.

Hopefully it is completely garbage collected, but I don’t know how to check for that though.

Nice!