LinkAnimClassLayers blocks the game thread.

We have our project set up similarly to Lyra, in that we have weapon class specific animation blueprints that use LinkAnimClassLayers to link and unlink as you equip/unequip weapon types.

When you call LinkAnimClassLayers, it triggers a HandleExistingParallelEvaluationTask with bBlockOnTask=true, causing a game thread stall. We see this hit 10ms quite often.

  • The ABPs are already loaded, this is not an asset load hitch.
  • Is there a way to perform these link/unlink operations off the main thread, or avoid the blocking task aspect?
  • Are there any other recommendations for managing this issue?

I

Hi, where is the call to LinkAnimClassLayers coming from in your setup? Is it originating from something like the weapon spawner actor, like we have in Lyra?

If you’re seeing a wait on HandleExistingParallelEvaluationTask when performing the linking, it’s because the evaluation of the parent anim instance’s anim graph is in flight when that function has been called. So we need to wait for evaluation to complete before we can do the linking. The solution is just to either perform the linking earlier or later in the frame. Unfortunately, there’s no automated way to do this, but one option would be to have a tick dependency on the mesh(es) so you would know for sure that the evaluation has completed. You could also use a different tick group, if you know for sure that the evaluation will have completed (or won’t have started) at that point. Or you can call IsRunningParallelEvaluation directly on the mesh to check the status.

Yeah, if you had a tick prerequisite set on the mesh component to make sure the pawn’s tick runs before it, I think that should give you what you need. If that doesn’t work for some reason, let me know and I can dig into that.

We have a delegate that fires from our inventory component when an item is equipped, which typically occurs during the tick of the player character pawn, during say interaction code execution.

Looks like APawn uses TG_PrePhysics, same as USkeletalMeshComponent.

Perhaps a tick dependency of APawn to run before its USkeletalMeshComponent would let this sort of state change occur before the async mesh stuff is kicked off?