I’m getting the following assert when trying to spawn in a Level Instance (LI) which contains a Packed Level Actor (PLA):
Assertion failed: GIsReinstancing || Value == nullptr || Value == LevelInstance [File:..\Engine\Source\Runtime\Engine\Private\LevelInstance\LevelInstanceSubsystem.cpp] [Line: 199]
Engine version - 5.7.1 source build
I’m using ULevelStreamingDynamic::LoadLevelInstanceBySoftObjectPtr to load in my level instance. I’m not using World partitioning on my map.
Edit - This is all editor time generation. My intention is to not use this for runtime generation.
After some initial debugging, I can confirm that the GUID for the PLA in the LI that spawns after the first one is the same which causes Value == LevelInstance to be true and the assert to fire in ULevelInstanceSubsystem::RegisterLevelInstance.
The PLA only contains HierarchicalInstancedStaticMeshes.
I can also confirm that this assert doesn’t fire if the PLA is removed from the LI.
I’ve got a couple of ideas for fixing this but I’m not sure if that’s the intended way to approach this.
Idea 1 - Remove PLAs from the LIs and spawn them separately
Idea 2 - Create a new child class of APackedLevelActor and use it instead of the default one. Then give it a new GUID in PostInitializeComponents. I’m not sure what the consequences of this could be.
I would like to keep using the workflow of having PLA(s) in LIs but I’m open to pivot if required
Create a packed level actor containing HierarchicalInstancedStaticMeshes or StaticMeshes
Create a level instance with the above packed level actor
While in the editor, try to load 2 or more of the above level instances using ULevelStreamingDynamic::LoadLevelInstanceBySoftObjectPtr or ULevelStreamingDynamic::LoadLevelInstance via a function callable in the editor
Observe that the assert fires for all instances after the first one
[Attachment Removed]
The assert you are hitting means there is a collision when the FLevelInstanceID is generated. This value is hashed in the constructor of the class. I recommend debugging there to understand where is the collision coming from. I suspect the LevelInstanceActor is not stable for networking (IsNameStableForNetworking).
I recommend that you change the way the new instances are created. The regular editor paths are doing it through the UActorFactory when the Level is dragged from the content browser. The spawned LevelInstanceActor registers to the subsystem and then trigger a load of the level. This is different from what you seem to be doing.
I have debugged how the FLevelInstanceID is generated and the conflict is coming from FLevelInstanceActorGuid::GetGuid_Internal. In the editor, the code that executes is this:
Since it is not the game world, it defaults to using the Actor->ActorGuid for the packed level actor in level instance. This causes the generated FLevelInstanceIDs to be the same for all spawned PLAs in the duplicated level instances and hits the assert.
“I recommend that you change the way the new instances are created. The regular editor paths are doing it through the UActorFactory when the Level is dragged from the content browser”
(Apologies if this sounds stupid ('^.^))
I looked at how level instances are spawned when you drag and drop them in the editor. As my use case is primarily to spawn the level instances in the editor and not at runtime, would you recommend going via the placement subsystem or directly via the ULevelInstanceActorFactory?
Apologies for the late reply. I can confirm that spawning the level instances using this method no longer causes the assert.
Spawning in a new ALevelInstance and then assigning it the asset and then loading it also does the job for me and I’ll be using that instead of the factory method for now.