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
inOnBeginFrame
and does the line traces inOnEndFrame
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:
- Frame 1: ComponentTick calling
RefreshBoneTransforms
- Frame 2: manually calling
RefreshBoneTransforms
- 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