top of page

How to check if a Data Layer has been loaded.

1 day ago
2 min read

I needed a way to check if a data layer was done loading so it would automatically open some doors when it was done loading. The Valley of the Ancient had an example of how to do it in blueprints using a Timer by Event which would construct a query and check specific data layers.


I took that and created a latent node version that checks if all partition streaming is complete as i didn't need to check specific data layers. I did this to keep the graph flow cleaner for our team.


I've included the code and also the blueprint example.



How Valley of the Ancient implements it in Blueprints (UE 5.7)

The two Blueprints you need to look at are BP_DarkWorldRift and BP_AncientGameMode.


DarkWorldRift has a function called SwapDataLayers and, the relevant bits,:

  1. apply a custom high priority loading implemented in c++ (which might be needed for a big world but i don't)

  2. binds to an OnTranistionComplete delegate on he GameMode

  3. calls BeginDarkWorldTransition and passes the PlayerCharacter's location


OnTranistionComplete:

  1. Applies default priority loading

  2. Force Garbage Collection




In AncientGameMode, the BeginDarkWorldTransition function:

  1. unloads the current data layer

  2. flushes streaming

  3. starts a 0.01 Timer by Event which calls ReadyToLoad


The ReadyToLoad function has the streaming complete check. It's a custom BP function.

  1. Test Streaming

    • It takes a DataLayerActor which seems like the only way to get the FName of a data layer currently.

    • And the Query Source Location which is the PlayerCharacter that was passed.

  2. Then afterwards it loads the DarkWorld and starts another 0.01 Timer by Event which calls CheckReadyToReveal which calls the same TestStreaming function and then calls the EventDispatcher


The TestStreamingState function:

  1. gets all the ActorDataLayerNames from the params

  2. Uses that to construct a query Source

  3. uses the IsStreamingCompleted function that's part of the World Partition Subsystem




I made a Latent Action Node (UE 5.7)

It might be easier to read on the Unreal Community


WaitForAllStreamingCompletion.h

#pragma once
#include "WorldPartition/WorldPartitionHelpers.h"
#include "WorldPartition/WorldPartitionSubsystem.h"
 
class FWaitForAllStreamingCompletion : public FPendingLatentAction
{
	
public:
	FName ExecutionFunction;
	int32 OutputLink;
	FWeakObjectPtr CallbackTarget;

	UWorldPartitionSubsystem* WorldPartitionSubsystem;

	FWaitForAllStreamingCompletion(const FLatentActionInfo& LatentInfo):
ExecutionFunction(LatentInfo.ExecutionFunction)
	, OutputLink(LatentInfo.Linkage)
	, CallbackTarget(LatentInfo.CallbackTarget)
{
	if (UWorld* World = GEngine->GetWorldFromContextObjectChecked(CallbackTarget.Get()))
	{
		WorldPartitionSubsystem = World->GetSubsystem<UWorldPartitionSubsystem>();
	}
}

virtual void UpdateOperation(FLatentResponse& Response) override
{
	if (!WorldPartitionSubsystem)
	{
		Response.DoneIf(true);
	}
	
	Response.FinishAndTriggerIf(WorldPartitionSubsystem->IsAllStreamingCompleted(), ExecutionFunction, OutputLink, CallbackTarget);
	}
};
UFUNCTION(BlueprintCallable, Category="WorldPartition|DataLayers", meta=(Latent, WorldContext="WorldContextObject", LatentInfo="LatentInfo"))

	static void	WaitForAllStreamingCompletion(const UObject* WorldContextObject, struct FLatentActionInfo LatentInfo );
void USystemLibrary::WaitForAllStreamingCompletion(const UObject* WorldContextObject, struct FLatentActionInfo LatentInfo)
{
	if (UWorld* World = GEngine->GetWorldFromContextObject (WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
		FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
	if (LatentActionManager.FindExistingAction <FWaitForAllStreamingCompletion>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr)
		{		LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FWaitForAllStreamingCompletion(LatentInfo));
		}
	}
}

Comments


bottom of page