TransformOrigin in Level Sequence fails with non-trivial subsequence hierarchy

We’re having a problem with LevelSequencer when using the TransformOrigin system to animate the transform of the whole LevelSequence. It seems that the more nested levels of subsequences containing subsequences we have, the more likely the whole system ‘breaks’ and leaves behind any number of objects in these subsequences.

Looking into the problem a bit it appears to me that this is an issue with the sorted InstanceHandleToParentHandle array in UMovieSceneTransformOriginSystem. The intention when this is sorted in UMovieSceneTransformOriginSystem::OnSchedulePersistentTasks is that the array can then be processed in a linear order where the parent transforms will always be processed before children transforms are calculated, but the naive implementation of the default Sort method being used does not take into account a hierarchy that is multiple levels deep. In this case you can’t just compare the node sort order according to “is node B a parent of node A” because that ignores that fact that the grand-parent node of child node A also needs to be processed before A.

I have locally implemented a more correct sorting algorithm to replace the simple Sort, and will continue to test it but it does not, unfortunately, seem to fix the broken case in the attached repro project.

Our quick test of an improved sorting algorithm in MovieSceneTransformOriginSystem.cpp to replace line 338):

`TMap<uint16, uint16> HierarchyMap, InstanceDepthMap;

for (const FInstanceToParentPair& Pair : InstanceHandleToParentHandle)
HierarchyMap.Add(Pair.Child.InstanceID, Pair.Parent.InstanceID);

for (const FInstanceToParentPair& Pair : InstanceHandleToParentHandle)
{
uint16 InstanceID = Pair.Child.InstanceID;
uint16 Depth = 0, CurrentID = InstanceID;
while (HierarchyMap.Contains(CurrentID))
{
Depth++;
CurrentID = HierarchyMap[CurrentID];
}
InstanceDepthMap.Add(InstanceID, Depth);
}

InstanceHandleToParentHandle.Sort([&InstanceDepthMap](const FInstanceToParentPair& A, const FInstanceToParentPair& B)
{
return InstanceDepthMap[A.Child.InstanceID] < InstanceDepthMap[B.Child.InstanceID];
});`

Steps to Reproduce
Create a LevelSequence containing Subsequences nested several levels deep (try at least 4), each with multiple objects. Then use the Origin Override to animate the base LevelSequence. We have noted that when there are multiple nested levels the transforms of some of the objects in the scene will NOT be updated.

The attached project has two master LevelSequences:

  • LS_Nested_Master: a nested example that is still working.
    • Hierarchy: LS_Nested_Master/LS_Nested_Platform/LS_Nested_Shot1/LS_Nested_Camera1
  • LS_Nested2_Master: a BROKEN case with a similar number of nested subsequences
    • Hierarchy: LS_Nested2_Master/LS_Nested2_Cubes/LS_Nested2_Shot1/LS_Nested2_Cam1

Hi [mention removed],

I’ve been investigating the attached project and was able to reproduce the issue by creating myself a nested Level Sequence. In my case, I couldn’t immediately identify what was wrong with LS_Nested2_Master, as all geometries appeared to move correctly — but as you mentioned, the issue does occur with my LevelSequence.

I’ll check whether this has been addressed in the latest version of the engine. If it hasn’t, I’ll make sure it’s reported to Epic so they can investigate and work on a fix.

Thanks again for bringing this to our attention.

Best regards,

Joan

To give a bit more of information, we have reported the issue to Epic as this issue has still not been solved in recent versions. Will update the thread once I get the crash report link.

Unreal Issue bug tracker: Unreal Engine Issues and Bug Tracker (UE\-282243)