Control Rig + Animation in Sequencer Can Lead to Unexpected Slider Reset

Hello,

Thank you for taking the time to look into this issue.

When a character has both a Control Rig track and an Animation track, interacting with any slider in Sequencer can be interrupted.

Explanation:

  1. The slider sends a value change event: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Source/Editor/MovieSceneTools/Private/CurveKeyEditors/SNumericKeyEditor.h#L134
  2. Sequencer then clears the cache for all its objects: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Source/Editor/Sequencer/Private/Sequencer.cpp#L2669
  3. The EntitySystemLinker invalidates the objects: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Source/Runtime/MovieScene/Private/EntitySystem/MovieSceneEntitySystemLinker.cpp#L233
  4. UMovieSceneGenericBoundObjectInstantiator unlinks invalidated objects: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Source/Runtime/MovieScene/Private/EntitySystem/MovieSceneBoundObjectInstantiator.cpp#L38
  5. UMovieSceneCachePreAnimatedStateSystem restores PreAnimated data: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Source/Runtime/MovieScene/Private/EntitySystem/MovieScenePreAnimatedStateSystem.cpp#L135
  6. The AnimInstance layer is recreated here: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Source/Runtime/AnimGraphRuntime/Public/AnimCustomInstanceHelper.h#L178
  7. Control Rig is rebound here: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Plugins/Animation/ControlRig/Source/ControlRig/Private/Sequencer/MovieSceneControlRigParameterTemplate.cpp#L609-L612
  8. This triggers a tree refresh here: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Plugins/Animation/ControlRig/Source/ControlRigEditor/Private/Sequencer/ControlRigParameterTrackEditor.cpp#L3729
  9. Which is caught by Sequencer here: https://github.com/EpicGames/UnrealEngine/blob/5.5/Engine/Source/Editor/Sequencer/Private/Sequencer.cpp#L2615

This results in the slider being reset (a reconstruction occurs), which can also lead to a stuck undo buffer as described here:

[Content removed]

This chain of events is not 100% deterministic and seems to depend on initialization order.

Muting and unmuting the Animation track makes the issue disappear.

In the opposite, muting and unmuting the Control Rig track makes the issue occur 100% of the time.

Thank you for your time and support.

[Attachment Removed]

Steps to Reproduce

  1. Add a reference to a pawn (BP_ThirdPersonCharacter)
  2. (If missing) Add a Control Rig track (CR_Mannequin_Body)
  3. Add an animation (MM_Jump)
  4. Mute the ControlRig track
  5. Unmute the ControlRig track
  6. Move any slider
    [Attachment Removed]

Additional note for “Stuck Undo Buffer” case

To prevent undo buffer corruption on our side, we wrapped the slider interaction in a scoped transaction that is explicitly started and ended with the slider lifecycle:

TUniquePtr<FScopedTransaction> SliderTransaction;
 
void OnBeginSliderMovement()
{
    SliderTransaction = MakeUnique<FScopedTransaction>(LOCTEXT("SetNumericKey", "Set Key Value"));
}
 
void OnEndSliderMovement(NumericType Value)
{
    SliderTransaction.Reset();
}

This ensures that the transaction is always properly closed, even if the underlying Sequencer state is rebuilt during the interaction.

[Attachment Removed]

Hey there,

Thanks for raising this. It is still happening in 5.7. I’ve logged an issue that you can track here: https://issues.unrealengine.com/issue/UE-372126

Many of the main developers are out at the moment, but I’ll see if they have any recommendations on code adjustments you could make to fix the issue.

Dustin

[Attachment Removed]