We’ve experienced an issue in our project with instances of UAIPerceptionStimuliSourceComponent that are on spatially loaded actors in World Partition. The first time these actors load in the component registers with the senses correctly and our AI correctly receive these stimuli. If the player wanders off and the actors unload and enough time passes for them to be fully garbage collected, then on returning and reloading the cell the actors and components are recreated as fresh UObjects and there are still no issues.
The issue we’ve seen however is with the functionality in world partition where if the player leaves and re-enters the cell before garbage collection completely removes the objects, and these UObjects are then re-used. When this occurs, the bSuccessfullyRegistered bool on UAIPerceptionStimuliSourceComponent is still true from the previous usage of the component. The external senses will have removed the actor from their tracking when the actor becomes invalid - for example we were seeing UAISense_Sight::Update remove the tracked actor from ObservedTargets due to the weak pointer to the actor now returning null, and so populating the InvalidTargets list with this target. Upon the player reloading the cell and reusing the same component, the call to UAIPerceptionStimuliSourceComponent::RegisterWithPerceptionSystem returns out at the top of the function as bSuccessfullyRegistered is still left as true but the component is no longer actually being tracked by any of the senses. With this, any AI is now unable to be stimulated by these components until the player leaves the cell, hits a garbage collection, and then re-enters the cell and creates the components as fresh UObjects.
This issue occurs with bAutoRegisterAsSource set as true, but would also happen if this was false and the component was registered at runtime without being manually unregistered before leaving the cell.
We have fixed this issue locally in our project by clearing the bSuccessfullyRegistered flag in an overridden OnUnregister function:
void UAIPerceptionStimuliSourceComponent::OnUnregister()
{
Super::OnUnregister();
bSuccessfullyRegistered = false;
}
With this change, the flag is cleared when the player leaves the cell and the actor is removed from tracking by the senses themselves - ensuring that the component is allowed to re-register with any senses if it gets reused. We considered calling UnregisterFromPerceptionSystem but at the very late stage in development we are at we wanted to attempt the simplest fix possible, and it looked like UAIPerceptionSystem::UnregisterSource performed logic that was not immediately clear to us on whether we desired this or not.
I’m assuming that others could experience this same issue, if so could it be worth adding this change to the main Unreal repo? If a different fix is desired then of course that would also be good. Let me know if you have any questions!
Thanks,
Tom