Crash with AI Perception in UAISense_Hearing::OnListenerRemovedImpl

The crash happens in the above named single-line method which is being called as a result of DestroyActor having been called on my AI character. No further debug info is available within the method call.

The character’s AI controller has a UAIPerceptionComponent, with both sight and hearing senses. The character itself is also registered as a perception source within its BeginPlay method.

It’s quite possible I’m using the perception system incorrectly in some way, however I had no issue until I added hearing as a second sense.

Using 4.7.5.

Thanks a lot for reporting this. I’ve filed a ticked and will investigate as soon as possible. I’ll get back to you when I figure out what’s wrong.

But while I’m here can you tell me if at the moment of crash there were any funky values being used? Like this being null, or ObjectFlags & RF_PendingKill != 0? Let me know if there’s anything worth mentioning.

Cheers,

–mieszko

I couldn’t get any valid debug symbols or anything at the point it crashed for some reason. I’ll try to build with source-built engine tomorrow and see if that helps me dig a bit deeper, then report back here.

Okay, so this error is proving to be a bit unpredictable, but it’s still there. The failure is at the following line:

DigestedProperties.FindAndRemoveChecked(UpdatedListener.GetListenerID());

The listener ID does not exist in the DigestedProperties array - it seems always to have an index lower than all those in the array. Whilst before it was in UAISense_Hearing, I am now getting it at the same line in UAISense_Sight.

Some other details:
In my base character class BeginPlay, I call the following:

PerceptionSys->RegisterSource< UAISense_Sight >(*this);
PerceptionSys->RegisterSource< UAISense_Hearing >(*this);

So as I understand it, this means all characters can generate sight and sound stimuli.

I have a base AI controller class with the AIPerception component. I derive a couple of blueprints from that, say AIContBP_X and AIContBP_Y. In the blueprint I configure X to have two senses, sight and hearing. Y has only one sense, hearing. When a character/controller of type Y is destroyed, I now get the error in UAISense_Sight::OnListenerRemovedImpl, even though the character which was destroyed did not have sight configured in its perception component.

Thanks for the detailed info! This is consistent with info I got from another fellow developer. It seems that if you have AI with different senses it can crash on closing PIE for example (I have a 100% local repro! :D).

One other thing that has been found is that if you register sense sources before a sense instance has been created in PerceptionSystem (which might be happening in your case since you do register sources early on) then the very first source registered for such a sense gets registered with invalid ID. A fix for this is going to submitted soon, but you can make the change yourself, it’s pretty straightforward. In function UAIPerceptionSystem::RegisterPerceptionStimuliSource this bit:

const FAISenseID SenseID = UAISense::GetSenseID(Sense);
if (AISys->GetPerceptionSystem()->IsSenseInstantiated(SenseID) == false)
{
	AISys->GetPerceptionSystem()->RegisterSenseClass(Sense);
}

Should be changed to this:

FAISenseID SenseID = UAISense::GetSenseID(Sense);
if (AISys->GetPerceptionSystem()->IsSenseInstantiated(SenseID) == false)
{
	AISys->GetPerceptionSystem()->RegisterSenseClass(Sense);
	SenseID = UAISense::GetSenseID(Sense);
}

(the proper fix in the engine is going to be slightly different)

Hi Mieszko, thanks for the quick response. I’m actually using the templated RegisterSource method and not RegisterPerceptionStimuliSource. The former appears to already have the short term fix in place in the version of github engine source I currently have, so I don’t think that’s the issue in this case.

I’ve done a little more digging, here’s what I see is happening.

Destroying the character/controller leads to UAIPerceptionSystem::UnregisterListener being called with the perception component owned by the destroyed controller. Currently in my case that component is configured with only a hearing sense. This method verifies that the component is a valid listener in the system before calling UAIPerceptionSystem::OnListenerRemoved.

This then loops through all senses registered with the perception system and calls the OnListenerRemoved delegate for each of them.
Now, I’m not all that clear on how the DigestedProperties member is used, but it looks to me like UAISense_Sight::OnListenerRemovedImpl and UAISense_Hearing::OnListenerRemovedImpl are making the assumption that if they are called, then the passed in listener must be listening to that sense. However it seems that all that has been checked up to this point, is that the listener is contained by the perception system, but not any specifics about which senses it is listening for. In my current case, the perception system has both sight and hearing senses registered, but the particular perception component being destroyed is only listening to one of those, and as such causes the failure when being ‘removed’ from a sense with which it is not actually registered.

Hope that helps.

Awesome, happy to help. Thanks Mieszko.
Is the plan for the perception system to be ready to use and get a bit of documentation or tutorial with 4.8 release, or is it likely to remain work in progress for a while longer?

You’re spot on! I’ve actually found it since my previous post myself, and I’m already testing a fix. I’ll bump the thread once my change makes it to github’s master branch.

Thanks a lot!

I’d like to push for 4.8 readiness, but the only documentation that will probably be ready will be whatever I put together. The system itself is used extensively by Fortnite, and the things that do not work or contain bugs now are things that Fortnite doesn’t use (so no internal test-cases :/).

So, ideally I would hope early adopters would use github master branch and report any single issue they found. Pretty please :smiley:

Okay, thanks for the info. I can’t develop on master branch for now, but will try to check against it before submitting issues at least.

Really appreciate your willingness to respond and help out despite how busy you are. Thanks again!