Description

Constraints (UTickableConstraint) are usually created throuh the "Animation" tab available in the Editor's "Animation Mode". When created through that interface while Sequencer is open, the internal UTransformableHandle used to store the link is assigned a FMovieSceneObjectBindingID, which ensures that the constraint can be resolved even when one of the participating actors is a Spawnable that gets despawned/respawned, or a Replaceable that gets replaced during playback. On the other hand, constraints created while Sequencer is not open are considered "static constraints" and owned by UConstraintsManager. The simplified flow is:

UE::Private::CreateConstraint()
UE::TransformConstraintUtil::CreateAndAddFromObjects()
UE::TransformConstraintUtil::AddConstraint()
FConstraintsManagerController::AddConstraint()
UConstraintSubsystem::AddConstraint()
if (WeakSequencer.IsValid())
FConstraintsManagerController::StaticConstraintCreated()
else
FControlRigParameterTrackEditor::AddConstraintToSequencer()
FMovieSceneConstraintChannelHelper::AddConstraintToSequencer()
FMovieSceneConstraintChannelHelper::CreateBindingIDForHandle()

Now, actor ACineCameraAttachMount from the "CineCameraRigs" plugin also creates a constraint internally in C++. But it does not account for the possibility of using a BindingID from an open Sequencer. It always follows the following simplified flow:

ACineCameraAttachMount::CreateConstraint()
UE::TransformConstraintUtil::CreateAndAddFromObjects()
UE::TransformConstraintUtil::AddConstraint()
FConstraintsManagerController::AddConstraint()
UConstraintSubsystem::AddConstraint()
FConstraintsManagerController::StaticConstraintCreated()

As a result, the constraint created by ACineCameraAttachMount does not work with Spawnables and Replaceables managed by Sequencer. Whenever an actor that participates in a constraint is recreated or replaced, the constraint link is broken.

 

Steps to Reproduce

1. Ensure the "CineCameraRigs" plugin is enabled
2. Create a new map from the "Basic" template
3. Place a new actor of type "Cube" at (0,0,50)
4. Place a new actor of type "Cine Camera Attach Mount" at (0,0,100)
4.1. On the details panel, set "Target Actor" to the Cube. Adjust the location back to (0,0,100)
5. Place a new actor of type "Cine Camera Actor" at (0,0,200)
5.1. Attach the CineCamera to the AttachMount by dragging in the Outliner. Keep resulting location of (0,0,100)
6. Create and edit a new Level Sequence
7. Drag the Cube to the sequence as a Possessable
7.1. Animate the Cube transform in any way (e.g. (0,0,50) at frame 0, (0,200,50) at frame 30)
7.2. Drag the playback head between the two keyframes. The cube will move, and the CineCamera will follow with a spring
8. Right-click the Cube on Sequencer and convert it to a Spawnable
8.1. Drag the playback head between the two keyframes. The CineCamera will not follow the Cube.
8.2. In the details panel for the Attach Mount, check that "Target Actor" has become invalid.
9. Set the "Target Actor" to the Cube again using the actor picker. CineCamera follows again.
10. On sequencer, create some keyframes for the "Spawned" track of the Cube (e.g. start true, then false at frame 10 and true at frame 15).
11. While dragging the playback head, the "Target Actor" reference will be broken every time the Cube despawns.
12. Similar behavior can be observed by making the Cube a Replaceable: changing the binding will break the "Target Actor" reference.

Workaround:

13. Clear the "Target Actor" on the details panel of the AttachMount
14. While sequencer is open, change the Editor from Selection Mode to Animation Mode (shift+8)
15. Select the AttachMount in the Viewport or Outliner.
16. In the "Animation" tab, add a new constraint of type "Parent" and pick the Cube as the parent
17. Convert the Cube to Possessable/Spawnable/Replaceable freely, despawn/respawn the cube, nothing will break the constraint binding

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-312651 in the post.

0
Login to Vote

Unresolved
CreatedAug 12, 2025
UpdatedSep 11, 2025
View Jira Issue