What is the event to check when all materials and textures are fully resolved or finished loading on a new spawned Actor?

I have a big project where it has a Persistent Level and doing multiple load level streaming here and there. However, one noticeable thing about it is that actors streamed in or newly spawned actors, get their actual instance accessible and ready yet their materials or textures are still in progress loading asynchronously (grey checkerboards).

I want to find a way to fully wait for my actors to be “fully loaded” before I hide my loading screen overlay and tell them to begin their thing, but I couldn’t figure out how to capture the loading progress? How do I do this? Is there an event I can bind to, or perhaps a function that I can poll?

I am open for both Blueprint or C++ approaches for this.

I am not fully sure about this, but I have been digging a little bit and found these:
Have you used these yet?
bild

The variable In Asset Data can be accessed by creating a new variable and setting it’s type to Asset Data.

Hi.

No I haven’t. But I need more information on these. Like when I have a variable of Asset Data, what and how do I set this variable. Do I need to take note of all actors in my level and check each of this?

What’s your flow/technique that uses those BlueprintPure functions?

I am still very much new to this as well as I recently found it. While researching the Asset Data node I came across Prestream Textures which could be useful for something in your case?

I’ll get back to you soon about the Asset Data information I have gathered.

bild

Here is some more information about the asset data. For my understanding the Asset Data can be useful for both developers and in the final build of the game to see if assets are loaded. Although I think it’s mostly aimed for us developers to check and see if content has been loaded. Here is a snippet of code from my work:

Finally, I think this is what you are looking for:

You can Async Load assets from Class or Object that you reference. The execution pins on the Async Load Primary Asset, will allow you to execute code when it completes the loading.

Hopefully all of this helped! :slight_smile:

Hi segfault_sigabrt,

Are you sure that the materials are still streaming and not that they’re compiling?

If it’s the latter, you can wait for the compiling to finish with a bit of code like below (brute force wait method).

void MyHelperClass::waitForShaderCompilation() {

#if ENGINE_MAJOR_VERSION>4 && ENGINE_MINOR_VERSION>0
	FWorldContext* worldctx=GEngine->GetWorldContextFromGameViewport(GEngine->GameViewport);
	if(worldctx) {
		UWorld* world=worldctx->World();
		if(world) {
			UMaterialInterface::SubmitRemainingJobsForWorld(world);
		}
	}
	FAssetCompilingManager::Get().FinishAllCompilation();
#else
	GShaderCompilingManager->FinishAllCompilation();
#endif
}

If you’re in runtime, you can just use the AActors* GetWorld() instead of the world context bit.

I use this is Editor utilities so I don’t know how thread friendly it is, but may be a starting point.

I’m not sure what the BP equivalent (if any) is…

Hi the above didn’t work for me.

The SubmitRemainingJobsForWorld(world); just caused an odd compiling shaders Editor box to appear when I start my game, which is a long wait. But upon reaching the content. The checkerboard surfaces still appears in the same manner, you have to wait at runtime for them to pop in completely.

It’s been a loooong time, but maybe this will be helpful for the prospectors from the future.
I was one of them, found this thread and it is not what I was looking for, but it led me to find the right (at least, working for me) way.

Right after your level is finished loading, you can block until all current streaming will be completed by doing this:

FStreamingManagerCollection& SMC = FStreamingManagerCollection::Get();
SMC.BlockTillAllRequestsFinished(0.f, true);

/**
 * Blocks till all pending requests are fulfilled.
 *
 * @param TimeLimit		Optional time limit for processing, in seconds. Specifying 0 means infinite time limit.
 * @param bLogResults	Whether to dump the results to the log.
 * @return				Number of streaming requests still in flight, if the time limit was reached before they were finished.
 */

One thing I can’t tell clearly is, where to put this lines of code, because in my case, I have my own code with my own events that dynamically loads and unloads levels, but one thing I can tell is, I’m using UGameplayStatics::LoadStreamLevel(); and UGameplayStatics::UnloadStreamLevel(); for this, along with FLatentActionInfo But I had the same issue as yours and FStreamingManagerCollection::BlockTillAllRequestsFinished(); solved it in my case.

1 Like

Thanks for posting/updating this! I’m going to try this on my side but the project that I’m working on that needed this is not my current assignment.

What I fully desire is just an event and letting things run/process instead of blocking. But this is better than nothing. I might even dig inside that function and see how it does it.

Hey, have you tried the solution from @N1ghtwish386 ?
I cant get it to work somehow.

I have some heavy materials that need quite some time to load on first game startup.
So the actors are already partially visible, but not completly while the materials are loaded in the PSOCache… would like to postpone the loading screen a bit longer until everything is properly visible