Hello all!
I’m new to working with the perception system and am having no end of trouble getting my AI controller’s perception component to broadcast its OnTargetPerceptionForgotten delegate in C++. I’m only concerned with sight at the moment and have successfully confirmed that the perception system and the sight sense are working, at least in so far as the AI controller can “see” the player pawn during the game. I have a function bound to the OnTargetPerceptionUpdated delegate, which is getting called as expected, but despite all my efforts I can’t figure out how to execute logic when a stimulus is “forgotten” (I have verified that the OnTargetPeceptionForgotten delegate has been bound in my AI controller).
In that controller’s BeginPlay (C++), I have set the AI System’s bForgetStaleActors bool to true (which I read was necessary for OnTargetPerceptionForgotten to fire), but this has made no difference. I also have initialized all the sight sense’s parameters to values that I at least think should work in the AI controller’s Blueprint (like making sure MaxAge is not 0), and I’ll include a pic of these settings below.
Again, I have gotten the AI’s perception component up and running to some extent, but even after manually “expiring” a perceived stimulus in my code, OnTargetPerceptionForgotten is radio silent.
If anyone has any knowledge to get this working (preferably in C++), I would be ever so grateful! Apart from that, if anyone can recommend any good C++ AI Perception resources, I would also be very glad to know of them. Thank you!
Settings for sight sense in AI Controller Blueprint
Hello! One reason I can think of is that the pawn is still in sight after discarding the stimulus. If the pawn is successfully sensed on the next frame the perceived actor can’t be considered as forgotten.
The only place where OnTargetPerceptionForgotten is triggered is in UAIPerceptionComponent::ProcessStimuli(), so manually discarding a stimuli won’t broadcast the event, and if the pawn is still in sight a new stimuli will be created the next frame.
Thank you for providing that insight! Unfortunately, the player should definitely leave the AI’s line of sight, at least I would think so based on the values I provided for the sight config parameters in the AI controller. It is good to know why manually expiring the stimulus is having no effect though. Time for me to dive back into the source code …
For sure, I don’t know what drives me more insane, the fact that I can’t get this to work as expected, or the barren landscape of despair that is the AI Perception documentation. I can more or less implement the logic I want using the OnTargetPerceptionUpdated delegate, but obviously the “Forgot” delegate is there for a reason and I would like to figure it out. Anyhow, I appreciate your help and thanks for the links!
Hi, I would set breakpoints in the code to try to debug it. It seems to be only called inside the ProcessStimuli function of the AIPerceptionComponent, so I would put a breakpoint where it is broadcasted and another one where it adds to ActorsToForget (since it calls the Delegate on those actors) and then also make sure that the ProcessStimuli function is also called when a stimulus expires. Cause in the source code there seems to be a check whether it should also call this function when a stimulus expires (WantsToNotifyOnlyOnPerceptionChange inside AIPerceptionTypes.h), which seems to default to false → it may not call the ProcessStimuli function when a stimulus expires and therefore won’t call the Delegate.
Apart from that, if anyone can recommend any good C++ AI Perception resources
For me getting to understand the perception system a bit was only through reading the source code and setting breakpoints in the code
Hi Penguenin,
You set bForgetStaleActors through the UAISystem. This class has a static function, UAISystem::GetCurrent (also GetCurrentSafe) that you can use to return a pointer to it. You can then set bForgetStaleActors directly using that pointer.
After much digging, I finally solved your (our) problem!
The problem with setting bForgetStaleActors with the GetCurrent() method in BeginPlay is that by then it’s too late to actually matter.
You see, the UAIPerceptionComponent class does not use bForgetStaleActors from UAISystem, but it’s own bForgetStaleActors that it sets on its constructor with this line: