I’m using the Data Layer Subsystem to manage multiple data layers in a level. However, I’m having trouble finding how I can query or get a callback when all the actors in a Data Layer are finished loading and are active in the world.
To add context, I have a data layer for a main menu scene, and a data layer for a store scene. The goal here is to allow us to make multiple levels that we can swap in and out as we see fit (by dragging them into the world and assigning them a data layer). When transitioning to the store, we activate the store data layer and set the main menu data layer to loaded. I need to wait for all the actors to finish loading into the world before I can query the camera from the store scene that I want to blend to.
So i came across this issue too, and found a decent solution, which was to hook into the callback for Level Instance loading. This obviously works because our game is primarily loading in Level Instances through World Partition, so may not be applicable for everyone.
We are dealing with the same issue using BPs in 5.3. It seems that a lot of functions for Data Layer management are simply not there and we struggle to understand the usefulness of runtime Data Layer control if it will result in screen freezing and objects appearing suddenly out of nowhere in front of the player.
To get around this issue, the developer needs to (a) know when the Data Layer has finished being Activated and also (b) control the rate of Loading/Activation. If we can’t have (b), then at least we need (a).
Weren’t Data Layers introduced in Unreal 5.0? What can we do to get some functionality out for this? (We are not using Level Instances right now so that method wouldn’t work).
We discovered that the answer lies in the Valley of the Ancient demo. You can use the method “IsStreamingCompleted” from the WorldPartitionSubsystem. Had to dig through that big project because finding the answer online did not yield any results. Of course, this solves only the (a) part. Still need to figure out the answer for (b).
You can wrap “Set data layer runtime state” into a latent function along with WorldPartitionSubsystem->IsStreamingCompleted() to get an async node that returns when all data layers have fully loaded:
The above code uses the wonderful Unreal coroutines library, if you can’t or don’t want to use coroutines you will have to use one of the default engine async methods
Thank you very much for sharing this! I’m very novice when it comes to C++ but have started studying this code to get an understanding of it. When you said that it’s an async node, do you mean that it will load/unload Data Layer assets asynchronously, so that assets are handled in the background off of the main thread?
Unreal has since deprecated DataLayerSubsystem (it’s still there in 5.3) and replaced it with the DataLayerManager, whose SetDataLayerRuntimeState uses Data Layer Asset objects instead of Actor Data Layer structs. Because WorldPartitionStreamingQuerySource uses Data Layer names, it’s quite easy to get that from Actor Data Layer structs. We haven’t yet figured out how to get names from Data Layer Asset objects.
We’ve still yet to create an Async version of the SetDataLayerRuntimeState. The documentation on Data Layer functions from Unreal’s team is very, very lacking.