diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index bd2bed541..6b240ff83 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog]. ### Removed ### Fixed +- Constraints and Animations can be broken with Automatic MergeBone `#594` ### Security diff --git a/CHANGELOG.md b/CHANGELOG.md index e5f816845..2d3456457 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog]. ### Removed ### Fixed +- Constraints and Animations can be broken with Automatic MergeBone `#594` ### Security diff --git a/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs b/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs index dbdac5e25..72e4c078a 100644 --- a/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs +++ b/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs @@ -356,30 +356,48 @@ private void ConfigureMergeBone() { ConfigureRecursive(_session.GetRootComponent(), _modifications); - // returns true if merged - bool ConfigureRecursive(Transform transform, ImmutableModificationsContainer modifications) + // returns (original mergedChildren, list of merged children if merged, and null if not merged) + //[CanBeNull] + (bool, List) ConfigureRecursive(Transform transform, ImmutableModificationsContainer modifications) { var mergedChildren = true; + var afterChildren = new List(); foreach (var child in transform.DirectChildrenEnumerable()) - mergedChildren &= ConfigureRecursive(child, modifications); + { + var (newMergedChildren, newChildren) = ConfigureRecursive(child, modifications); + if (newChildren == null) + { + mergedChildren = false; + afterChildren.Add(child); + } + else + { + mergedChildren &= newMergedChildren; + afterChildren.AddRange(newChildren); + } + } const ComponentDependencyCollector.DependencyType AllowedUsages = ComponentDependencyCollector.DependencyType.Bone | ComponentDependencyCollector.DependencyType.Parent | ComponentDependencyCollector.DependencyType.ComponentToTransform; + // functions for make it easier to know meaning of result + (bool, List) YesMerge() => (mergedChildren, afterChildren); + (bool, List) NotMerged() => (mergedChildren, null); + // Already Merged - if (transform.GetComponent()) return true; + if (transform.GetComponent()) return YesMerge(); // Components must be Transform Only - if (transform.GetComponents().Length != 1) return false; + if (transform.GetComponents().Length != 1) return NotMerged(); // The bone cannot be used generally - if ((_marked[transform] & ~AllowedUsages) != 0) return false; + if ((_marked[transform] & ~AllowedUsages) != 0) return NotMerged(); // must not be animated - if (TransformAnimated(transform, modifications)) return false; + if (TransformAnimated(transform, modifications)) return NotMerged(); if (!mergedChildren) { - if (GameObjectAnimated(transform, modifications)) return false; + if (GameObjectAnimated(transform, modifications)) return NotMerged(); var localScale = transform.localScale; var identityTransform = localScale == Vector3.one && transform.localPosition == Vector3.zero && @@ -387,22 +405,21 @@ bool ConfigureRecursive(Transform transform, ImmutableModificationsContainer mod if (!identityTransform) { - var childrenTransformAnimated = - transform.DirectChildrenEnumerable().Any(x => TransformAnimated(x, modifications)); + var childrenTransformAnimated = afterChildren.Any(x => TransformAnimated(x, modifications)); if (childrenTransformAnimated) // if this is not identity transform, animating children is not good - return false; + return NotMerged(); if (!MergeBoneProcessor.ScaledEvenly(localScale)) // non even scaling is not possible to reproduce in children - return false; + return NotMerged(); } } if (!transform.gameObject.GetComponent()) transform.gameObject.AddComponent().avoidNameConflict = true; - return true; + return YesMerge(); } bool TransformAnimated(Transform transform, ImmutableModificationsContainer modifications)