diff --git a/.docs/content/docs/reference/merge-bone/component.png b/.docs/content/docs/reference/merge-bone/component.png index 98f5a1471..d2c7f5aea 100644 Binary files a/.docs/content/docs/reference/merge-bone/component.png and b/.docs/content/docs/reference/merge-bone/component.png differ diff --git a/.docs/content/docs/reference/merge-bone/index.ja.md b/.docs/content/docs/reference/merge-bone/index.ja.md index 652ac9711..6468e44e2 100644 --- a/.docs/content/docs/reference/merge-bone/index.ja.md +++ b/.docs/content/docs/reference/merge-bone/index.ja.md @@ -11,6 +11,8 @@ weight: 100 このコンポーネントが付いているGameObjectの全ての子GameObjectは、その親GameObjectの子になります。 -今のところ、このコンポーネントに設定項目はありません。 +## 設定 {#settings} ![component.png](component.png) + +- `名前の競合を避ける` 統合時に子GameObjectの名前を変更することで、名前の重複によってアニメーションが正しく動かなくなる問題を回避します。 diff --git a/.docs/content/docs/reference/merge-bone/index.md b/.docs/content/docs/reference/merge-bone/index.md index 97a9afa1c..8d1d05371 100644 --- a/.docs/content/docs/reference/merge-bone/index.md +++ b/.docs/content/docs/reference/merge-bone/index.md @@ -13,4 +13,8 @@ All children of GameObject this component is applied to will belongs to parent o This Component doesn't have any configuration for now. +## Settings + ![component.png](component.png) + +- `Avoid Name Conflict` Avoids animation problems with name conflict by renaming child GameObjects diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index ce5b3842b..adb2cf4e1 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog]. ## [Unreleased] ### Added +- Avoid Name Conflict in MergeBone `#467` ### Changed @@ -17,6 +18,7 @@ The format is based on [Keep a Changelog]. ### Fixed - Light disappears `#466` +- Automatic MergeBone may break Animation by conflictng GameObject name `#467` ### Security diff --git a/CHANGELOG.md b/CHANGELOG.md index d5935c8e5..1b103c943 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog]. - Moved `Use Advanced Animator Parser` to there - Added `Exclusions` for exclude some GameObjects from optimization - In this section, there are for debugging GC Objects `#464` +- Avoid Name Conflict in MergeBone `#467` ### Changed - Improved 'Remove Unused Objects' `#401` diff --git a/Editor/Processors/MergeBoneProcessor.cs b/Editor/Processors/MergeBoneProcessor.cs index 9099f71f5..fe6a12c44 100644 --- a/Editor/Processors/MergeBoneProcessor.cs +++ b/Editor/Processors/MergeBoneProcessor.cs @@ -70,19 +70,24 @@ public void Process(OptimizerSession session) DoBoneMap2(meshInfo2, mergeMapping); }); + var counter = 0; + foreach (var pair in mergeMapping) { var mapping = pair.Key; var mapped = pair.Value; + var avoidNameConflict = mapping.GetComponent().avoidNameConflict; // if intermediate objects are inactive, moved bone should be initially inactive // animations are not performed correctly but if bones activity is animated, automatic // merge bone doesn't merge such bone so ignore that for manual merge bone. - var activeSelf = ActiveSelfForNow(mapping, mapped); + var (activeSelf, namePrefix) = ActiveSelfAndNamePrefix(mapping, mapped); foreach (var child in mapping.DirectChildrenEnumerable().ToArray()) { if (mergeMapping.ContainsKey(child)) continue; child.parent = mapped; if (!activeSelf) child.gameObject.SetActive(false); + if (avoidNameConflict) + child.name = namePrefix + "$" + child.name + "$" + (counter++); } } @@ -90,11 +95,19 @@ public void Process(OptimizerSession session) if (pair) Object.DestroyImmediate(pair.gameObject); - bool ActiveSelfForNow(Transform transform, Transform parent) + (bool activeSelf, string namePrefix) ActiveSelfAndNamePrefix(Transform transform, Transform parent) { + var segments = new List(); + var activeSelf = true; for (; transform != parent; transform = transform.parent) - if (!transform.gameObject.activeSelf) return false; - return true; + { + segments.Add(transform.name); + activeSelf &= transform.gameObject.activeSelf; + } + + segments.Reverse(); + + return (activeSelf, string.Join("$", segments)); } } diff --git a/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs b/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs index 7378d170d..fa3835d1a 100644 --- a/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs +++ b/Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs @@ -336,7 +336,8 @@ bool ConfigureRecursive(Transform transform, ImmutableModificationsContainer mod } } - transform.gameObject.GetOrAddComponent(); + if (!transform.gameObject.GetComponent()) + transform.gameObject.AddComponent().avoidNameConflict = true; return true; } diff --git a/Localization/en.po b/Localization/en.po index 1d66050df..d10940117 100644 --- a/Localization/en.po +++ b/Localization/en.po @@ -88,6 +88,12 @@ msgstr "Execute Early doesn't support Animation Remapping. Make sure you made an msgid "MergeBone:description" msgstr "You will remove this GameObject and merge bone to parent" +msgid "MergeBone:prop:avoidNameConflict" +msgstr "Avoid Name Conflict" + +msgid "MergeBone:tooltip:avoidNameConflict" +msgstr "Renames child GameObjects to avoid name conflict" + msgid "MergeBone:validation:thereAreComponent" msgstr "There are some components other than Transform. This is not supported." diff --git a/Localization/ja.po b/Localization/ja.po index 9a7b26104..d3ef8a7a2 100644 --- a/Localization/ja.po +++ b/Localization/ja.po @@ -91,6 +91,12 @@ msgstr "'早期に実行する'はアニメーションのパス修正が動き msgid "MergeBone:description" msgstr "このGameObjectを削除して親に統合する。" +msgid "MergeBone:prop:avoidNameConflict" +msgstr "名前の競合を避ける" + +msgid "MergeBone:tooltip:avoidNameConflict" +msgstr "統合時に子GameObjectの名前を変更し、名前の重複を回避します" + msgid "MergeBone:validation:thereAreComponent" msgstr "Transform以外のコンポーネントがあります。これはサポートされていません。" diff --git a/Runtime/MergeBone.cs b/Runtime/MergeBone.cs index d51725508..50ebbca12 100644 --- a/Runtime/MergeBone.cs +++ b/Runtime/MergeBone.cs @@ -1,4 +1,5 @@ using Anatawa12.AvatarOptimizer.ErrorReporting; +using CustomLocalization4EditorExtension; using UnityEngine; namespace Anatawa12.AvatarOptimizer @@ -7,5 +8,14 @@ namespace Anatawa12.AvatarOptimizer [DisallowMultipleComponent] [HelpURL("https://vpm.anatawa12.com/avatar-optimizer/ja/docs/reference/merge-bone/")] internal class MergeBone : AvatarTagComponent, IStaticValidated - { } + { + [CL4EELocalized("MergeBone:prop:avoidNameConflict", "MergeBone:tooltip:avoidNameConflict")] + [ToggleLeft] + public bool avoidNameConflict; + + private void Reset() + { + avoidNameConflict = true; + } + } }