When a subsequence (or cinematic shot - which is a subclass and behaves the same) section has pre- or post-roll frames, tracks in the referenced child sequence should only be played during those frames if they are enabled to do so. However, they can be evaluated even when disabled between leaving the main part of the subsequence section and leaving the pre- or post-roll frames.
I originally found this issue on a from-source build of Unreal 5.4.4, and after a little debugging the issue appeared to be due to the ledger invalidation not taking effect unless FEntityLedger::UpdateEntities is called, which is skipped on the last frame of the main part of the subsequence section (being called inside the conditional shown below).
Given that, I was hopeful the issue had been fixed in Unreal 5.5 when I saw that the conditional had been changed from this:
// Unreal 5.4.4 - MovieSceneSequenceUpdaters.cpp:715 - FSequenceUpdater_Hierarchical::Update if (bGatherEntities)
… to this:
// Unreal 5.5.4 - MovieSceneSequenceUpdaters.cpp:930 - FSequenceUpdater_Hierarchical::Update if (bGatherEntities || SubSequenceInstance.Ledger.IsInvalidated())
… However, since I’ve been able to reproduce the same issue on Unreal 5.5.4 (from the launcher), it appears the issue is not fixed by that change.
Due to these changes (and the fact I only have a source build of 5.4 at the moment - and not 5.5), that seemed a good point to stop investigating and raise this UDN ticket.
Thanks,
Haddon.
Steps to Reproduce
- Create a level sequence (this will be our sub-sequence)
- Bind an actor in the sequence, and animate its transform
- Note that in the transform track properties both “Evaluate in Preroll” and “Evaluate in Postroll” are disabled by default
- Create another level sequence (this will be our parent sequence)
- Add the sub-sequence to the parent sequence
- Reduce the length of the sub-sequence section so that only a small part of the child sequence is included in the parent
- Add pre- and post-roll frames to the sub-sequence section
- This should have no effect on the playback of the parent sequence, because all tracks in the sub-sequence are disabled in pre- and post-roll
- Scrub the sequence forward and backwards in the editor
- The actor’s transform should animate in only the main section, but actually begins animating whenever the main section is entered and only stops animating when exiting the section completely - i.e. leaving pre- or post-roll
- Play the sequence forwards during gameplay
- The actor’s transform should animate in only the main section, but actually animates in both the main section and in postroll
- Play the sequence backwards during gameplay
- The actor’s transform should animate in only the main section, but actually animates in both the main section and in preroll (which is after the main section, because we’re playing backwards)
The attached zip file contains a level, parent sequence and child sequence that reproduce the issue as described above. The child sequence animates the cube, moving it in a loop five times (and the orientation of the cube is different for each loop, so you can tell them apart). The parent sequence has a sub-sequence section for only the middle (third) loop, but that section has pre- and post-roll for the duration of the second and fourth loops respectively. The level alternately plays the sequence forwards and backwards. Because the transform track in the child sequence has both “Evaluate in Preroll” and “Evaluate in Postroll” disabled, you should only see the cube move in a single loop each time, in the same orientation. However, each time the sequence plays, you see two loops - first the main section (always in the same orientation) followed by a second loop - either the postroll when forwards or the preroll when backwards (you can tell them apart by the orientation of the cube).
It looks like when editing the above “Steps to Reproduce” post it might have lost the attached zip file. So here it is again.
Hello! Sorry for the trouble and thanks for the test data, it really helps.
So at least with UE 5.6, it looks like the problem is we don’t clean up the imported Sequencer entities once we exit the section and go into post-roll (when playing forward) or pre-roll (when playing backward).
We’ll fix this in 5.6.1 or 5.7, but the fix boils down to replacing the two early return statements inside `FEntityLedger::ImportEntity` with the following:
bool bUnsupportedPrePostRoll = false; if (ImportParams.bPreRoll && (Params.EntityMetaData == nullptr || Params.EntityMetaData->bEvaluateInSequencePreRoll == false)) { bUnsupportedPrePostRoll = true; } else if (ImportParams.bPostRoll && (Params.EntityMetaData == nullptr || Params.EntityMetaData->bEvaluateInSequencePostRoll == false)) { bUnsupportedPrePostRoll = true; } if (bUnsupportedPrePostRoll) { if (EntityData.EntityID) { // If we are reimporting an existing entity and we entered a pre/post-roll time range // that this entity shouldn't update in, we need to delete that entity. Linker->EntityManager.AddComponents(EntityData.EntityID, FBuiltInComponentTypes::Get()->FinishedMask, EEntityRecursion::Full); EntityData.EntityID = FMovieSceneEntityID(); } return; }