Hi. This is kind of complex issue I faced with auto saves for streamed out levels.
While testing the feature, I noticed dynamically spawned actors in sublevels were failing to save their data into SPUD while their level is streaming out. After extensive debugging, I noticed it's because plugin tries to save data of those actors "after" level is streamed out, so actors have a null UWorld reference during the operation.
The root cause was, all of ISpudObject and ISpudObjectCallback interface functions were failing to execute for those actors during the stream out save process. I noticed AActor::ProcessEvent function is responsible with initiating interface calls, and it has a check for validity of actor's world:
UWorld* MyWorld = GetWorld();
if( ((MyWorld && (MyWorld->AreActorsInitialized() || bAllowScriptExecution)) || HasAnyFlags(RF_ClassDefaultObject)) && !IsGarbageCollecting() )
{
#if !UE_BUILD_SHIPPING
if (!ProcessEventDelegate.IsBound() || !ProcessEventDelegate.Execute(this, Function, Parameters))
{
Super::ProcessEvent(Function, Parameters);
}
#else
Super::ProcessEvent(Function, Parameters);
#endif
}
So, all interface calls were just being ignored for Spud because of that.
As solution, I honestly didn't like what was done in #45 to monitor load/unload state of streamed levels in tick function of spud subsystem. LevelStreamingDelegates.cpp from engine source already has two good callbacks for SpudSubsystem to bind itself:
TMulticastDelegate<void(UWorld*, const ULevelStreaming*, ULevel* LoadedLevel)> FLevelStreamingDelegates::OnLevelBeginMakingVisible;
TMulticastDelegate<void(UWorld*, const ULevelStreaming*, ULevel* LoadedLevel)> FLevelStreamingDelegates::OnLevelBeginMakingInvisible;
After cleaning out MonitoredStreamingLevels stuff from subsystem and binding into those callbacks fixed the issue for me. Now, spud saves state of actors first, then the level streams out.
I might open a pull request, but I'm not able to test this change for WorldPartition at the moment, and not sure if this change breaks the compatibility.
Anyways, wanted to create this issue to give that problem some visibility.
Hi. This is kind of complex issue I faced with auto saves for streamed out levels.
While testing the feature, I noticed dynamically spawned actors in sublevels were failing to save their data into SPUD while their level is streaming out. After extensive debugging, I noticed it's because plugin tries to save data of those actors "after" level is streamed out, so actors have a null UWorld reference during the operation.
The root cause was, all of
ISpudObjectandISpudObjectCallbackinterface functions were failing to execute for those actors during the stream out save process. I noticedAActor::ProcessEventfunction is responsible with initiating interface calls, and it has a check for validity of actor's world:So, all interface calls were just being ignored for Spud because of that.
As solution, I honestly didn't like what was done in #45 to monitor load/unload state of streamed levels in tick function of spud subsystem.
LevelStreamingDelegates.cppfrom engine source already has two good callbacks for SpudSubsystem to bind itself:After cleaning out
MonitoredStreamingLevelsstuff from subsystem and binding into those callbacks fixed the issue for me. Now, spud saves state of actors first, then the level streams out.I might open a pull request, but I'm not able to test this change for WorldPartition at the moment, and not sure if this change breaks the compatibility.
Anyways, wanted to create this issue to give that problem some visibility.