UAIPerceptionStimuliSourceComponent failing to register with senses with World Partition

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

I believe your fix makes sense. I know we reset bSuccessfullyRegistered in the stimuli source component when the number of registered senses is set to 0 or it is unregistered from the perception system. Perhaps with placed actors in WP, we have not encountered this much ourselves. If the component has not been unregistered fully, you may want to unregister from the perception system rather than only change the registration bool.

-James

Hi James,

Thanks for responding - I can imagine it would probably be safest to fully unregister everything, but given we don’t fully understand all the potential consequences that calling that function may have we are wary of adding that call into our project at this point in time.

With AISense_Sight the actor does get fully removed by the sense logic as soon as the actor is no longer valid (but not yet garbage collected), so what we’re doing seems to be working for that sense at least - and this is the only sense we are hooking into with these stimuli source components. I would not be surprised if there might be other senses where manually requesting the unregister could be more effective! Though maybe any issues with those would have already been surfaced due to the stimuli source component already not manually unregistering on EndPlay.

Thanks,

Tom

Your solution makes sense, and if it is working, I would likely let it be. Perception has not seen much work outside of updating it to support Large World Coordinates in UE5. So I am not too surprised that some of the new things like re-using levels that have not yet been GC’d are finding some limitations of the system.

-James