How to make sure a SkeletalMesh with PerPolyCollision updates the physics scene before running a LineTrace?

Hi everyone,

I’m currently working on a project that requires accurate line trace hit results of an animated SkeletalMesh as a means of data collection. Since realtime performance is not necessary the SkeletalMesh has PerPolyCollision enabled to get the most accurate results (no PhysicsAsset approximation). Inside of a PIE session a UObject gets spawned that subscribes to the OnBeginFrame and OnEndFrame core delegates. This UObject then spawns a LevelSequenceActor with a LevelSequence containing the SkeletalMesh and animation. The SequencePlayer is set to pause in order to use SetPlaybackPosition with EUpdatePositionMethod::Jump to easily step through the sequence frame by frame.

So far so good, now comes the part that I’m uncertain about:
Initially I thought it should be possible to set the SequencePlayer position in OnBeginFrame and do the line traces in OnEndFrame since these delegates happen outside the regular world tick. But this doesn’t seem to work. From the ChaosVisualDebugger I can see that the physics mesh seems to be one or more frames behind the line traces which means the results can’t be correct. The line traces use the bone positions of the SkeletalMesh for calculating start and end of the trace but they seem to be updated correctly.

The only way that I got it to work was to use two consecutive frames and manually calling RefreshBoneTransforms:

  • Frame 1: Sets the sequencer position in OnBeginFrame
  • Frame 2: Calls RefreshBoneTransforms in OnBeginFrame and does the line traces in OnEndFrame

Even though this does actually work well, I have no real clue why and I’m sure this is not the intended way of doing it. This “solution” also means that performance is really bad since the expensive creation of the PerPolyCollision is done 3 times:

  1. Frame 1: ComponentTick calling RefreshBoneTransforms
  2. Frame 2: manually calling RefreshBoneTransforms
  3. Frame 2: ComponentTick calling RefreshBoneTransforms

I would really like to know if there is a better way of doing this. I have looked a lot at the SkeletalMeshComponent implementation but without any deeper knowledge about how physics is synced with the regular world I’m a bit clueless where to start. The collision mesh seems to be updated every frame without having to call anything manually (inside RefreshBoneTransforms and eventually PostAnimEvaluation then UpdateKinematicBonesToAnim and finally a call to BodyInstance.UpdateTriMeshVertices). All this happens before the OnEndFrame event so there is probably more going on in the background. Calling WaitPhysScenes and WaitSolverTasks right before also doesn’t have any effect.

Thank you,
Marcel