Cast To AiController Randomly Fails

Hello friends,
I am trying to cast to an AIController inside a BTTask blueprint. Problem is it fails sometimes, and succeeds other times. I’ve tested IsValid up the very point fails, but ALWAYS returns True.

As you can see I print out the result when it fails to cast, however IsValid returns true. How can it be valid yet still fail to cast? Really stuck on this one!

So, the “IsValid” will be checking to see if the object reference is valid. This means it’s checking to make sure that the value is not null, and that it is not marked for cleanup. This doesn’t care about whether casting is valid or not.

Your casting problem is different. When you’re casting one object to another, you’re pretty much telling the computer, “Hey, I know you think this object is a generic object of type X, but I know better than you and I’m telling you to interpret it as an object of type Y because that’s what it really is.”

You run into problems when the object you’re casting actually isn’t of type Y. Your blackboard key value is a generic object, so IF that object is anything other than AIController1 or something in that inheritance chain, you’re going to get a casting failure. I recommend using the “GetClass” node and comparing it against the AIController1 class, and if they aren’t the same, you should output an error message to the output log with the GetClass value.

When it comes to casting, it helps to think of this in terms of memory blocks. You can only cast an object downwards in the object inheritance hierarchy. So, the hierarchy chain for your AIController looks like this:

UObject → AActor → AController → AIController → AIController1

So, if you have a generic UObject and you cast it to AIController1, what’s happening on the backend is that the compiler is saying, “Hey, you see this object and the block of memory it occupies on the heap? I know you only know how the variables for the UObject are typed, but you can type the rest of the memory based off of the signature of the AIController1 class. So… like at offset X+50, the next 4 bytes would be an integer, etc.” You get into serious trouble though, when you’re wrong. If X+50 wasn’t an integer, it would be interpreted as an integer anyways and treated as an integer. In C++, this is one way you can shoot yourself in the foot if you really, really don’t know what you’re doing (Note: sometimes you can actually intend to cast something to something it’s not). A lot of compilers, API’s and engines will now do type checking to help avoid casting mistakes. Once you get your object casted to another object, the data in memory at various addresses will be interpreted as according to the class signature you casted to, and you can access the class specific variables. The casting failure is a safety measure to prevent you from accessing sections of memory if the class doesn’t match the class signature you’re casting to, because you might end up doing “really bad things”, such as redirecting a pointer address when you think you’re changing health values.

Anyways, long story short: Check your assigned behavior tree key values to be 1000% sure that you’re actually sending a value which can be casted to AIController1. If you send something like “self”, which is a character or pawn, that will break the inheritance chain and you’ll get a casting fail, and that’s easy to accidentally overlook…

Printing out the name of the thing that’s stored in the BB key will help you figuring out what’s there. How do you write stuff to BB? If you use EQS it will put a Pawn reference there, not a Controller.

One other helpful pro tip is that there’s a Get AI Controller which will return an AIController if there is any associated with a given actor (you’ll need to cast BB key’s contents to an Actor first though).

Cheers,

–mieszko

You are 100% correct, I was using controller, but I used the controlled pawn now; now it’s fixed. Thank you!

I passed the data via OnPerceptionUpdated, turns out was user error. I should’ve casted to Character (GetControlledPawn) in the task. Now it’s character and not controller. Your advanced AI video with Ian helped a lot! Thank you and please make more! :slight_smile: