GroomAsset causes synchronous load of "/HairStrands/Emitters/StableSpringsSystem.StableSpringsSystem"

We’ve been doing profiling of performance and ran across a LoadObject call coming from a GroomAsset.

We’re trying to avoid synchronous loading to improve performance.

I found where this occurs in the GroomAsset.cpp.

Is there a way around this and have it loaded asynchronously?

void UGroomAsset::UpdatePhysicsSystems()
{
	for (auto& Group : GetHairGroupsPhysics())
	{
		if (Group.SolverSettings.NiagaraSolver == EGroomNiagaraSolvers::AngularSprings)
		{
			Group.SolverSettings.CustomSystem = LoadObject<UNiagaraSystem>(nullptr, TEXT("/HairStrands/Emitters/StableSpringsSystem.StableSpringsSystem"));
		}
		else if (Group.SolverSettings.NiagaraSolver == EGroomNiagaraSolvers::CosseratRods)
		{
			Group.SolverSettings.CustomSystem = LoadObject<UNiagaraSystem>(nullptr, TEXT("/HairStrands/Emitters/StableRodsSystem.StableRodsSystem"));
		}
	}
}



Steps to Reproduce
Have a GroomAsset loaded

Hi there,

While you could probably get these to be completely asynchronously loaded, an easier solution would be to just pre-load these two Niagara systems, and hold a hard reference to them somewhere so they are never garbage collected. This way you can control when the assets load, and place them behind a loading screen or even game startup so they do not contribute to any runtime loading hitches.

A simple way to do this would be to make two NiagaraSystem properties on your projects GameInstance and assign these Niagara Systems to them. This way they will always be loaded in memory. Any further calls to LoadObject will just return the object already in memory.

Regards,

Lance Chaney