diff --git a/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs b/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs index b5642e6d3..13b2e76c6 100644 --- a/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs +++ b/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs @@ -75,56 +75,6 @@ namespace UniHumanoid } } - class UniqueName - { - HashSet m_uniqueNameSet = new HashSet(); - int m_counter = 1; - - public void ForceUniqueName(Transform t) - { - if (!m_uniqueNameSet.Contains(t.name)) - { - m_uniqueNameSet.Add(t.name); - return; - } - - if (t.parent != null && t.childCount == 0) - { - /// AvatarBuilder:BuildHumanAvatar で同名の Transform があるとエラーになる。 - /// - /// AvatarBuilder 'GLTF': Ambiguous Transform '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/neck_1/neck_2/head/ENDSITE' and '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/l_shoulder/l_up_arm/l_low_arm/l_hand/ENDSITE' found in hierarchy for human bone 'Head'. Transform name mapped to a human bone must be unique. - /// UnityEngine.AvatarBuilder:BuildHumanAvatar (UnityEngine.GameObject,UnityEngine.HumanDescription) - /// UniHumanoid.AvatarDescription:CreateAvatar (UnityEngine.Transform) - /// - /// 主に BVH の EndSite 由来の GameObject 名が重複することへの対策 - /// ex: parent-ENDSITE - var newName = $"{t.parent.name}-{t.name}"; - if (!m_uniqueNameSet.Contains(newName)) - { - Debug.LogWarning($"force rename: {t.name} => {newName}"); - t.name = newName; - m_uniqueNameSet.Add(newName); - return; - } - } - - // 連番 - for (int i = 0; i < 100; ++i) - { - // ex: name.1 - var newName = $"{t.name}{m_counter++}"; - if (!m_uniqueNameSet.Contains(newName)) - { - Debug.LogWarning($"force rename: {t.name} => {newName}"); - t.name = newName; - m_uniqueNameSet.Add(newName); - return; - } - } - - throw new NotImplementedException(); - } - } [Serializable] public class AvatarDescription : ScriptableObject @@ -177,13 +127,7 @@ namespace UniHumanoid public Avatar CreateAvatar(Transform root) { // force unique name - var uniqueName = new UniqueName(); - var transforms = root.GetComponentsInChildren(); - foreach (var t in transforms) - { - uniqueName.ForceUniqueName(t); - } - + ForceUniqueName.Process(root); return AvatarBuilder.BuildHumanAvatar(root.gameObject, ToHumanDescription(root)); } diff --git a/Assets/UniGLTF/Runtime/UniHumanoid/ForceUniqueName.cs b/Assets/UniGLTF/Runtime/UniHumanoid/ForceUniqueName.cs new file mode 100644 index 000000000..4b3c0f0a6 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniHumanoid/ForceUniqueName.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UniHumanoid +{ + class ForceUniqueName + { + HashSet m_uniqueNameSet = new HashSet(); + int m_counter = 1; + + public static void Process(Transform root) + { + var uniqueName = new ForceUniqueName(); + var transforms = root.GetComponentsInChildren(); + foreach (var t in transforms) + { + uniqueName.RenameIfDupName(t); + } + } + + public void RenameIfDupName(Transform t) + { + if (!m_uniqueNameSet.Contains(t.name)) + { + m_uniqueNameSet.Add(t.name); + return; + } + + if (t.parent != null && t.childCount == 0) + { + /// AvatarBuilder:BuildHumanAvatar で同名の Transform があるとエラーになる。 + /// + /// AvatarBuilder 'GLTF': Ambiguous Transform '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/neck_1/neck_2/head/ENDSITE' and '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/l_shoulder/l_up_arm/l_low_arm/l_hand/ENDSITE' found in hierarchy for human bone 'Head'. Transform name mapped to a human bone must be unique. + /// UnityEngine.AvatarBuilder:BuildHumanAvatar (UnityEngine.GameObject,UnityEngine.HumanDescription) + /// UniHumanoid.AvatarDescription:CreateAvatar (UnityEngine.Transform) + /// + /// 主に BVH の EndSite 由来の GameObject 名が重複することへの対策 + /// ex: parent-ENDSITE + var newName = $"{t.parent.name}-{t.name}"; + if (!m_uniqueNameSet.Contains(newName)) + { + Debug.LogWarning($"force rename !!: {t.name} => {newName}"); + t.name = newName; + m_uniqueNameSet.Add(newName); + return; + } + } + + // 連番 + for (int i = 0; i < 100; ++i) + { + // ex: name.1 + var newName = $"{t.name}{m_counter++}"; + if (!m_uniqueNameSet.Contains(newName)) + { + Debug.LogWarning($"force rename: {t.name} => {newName}"); + t.name = newName; + m_uniqueNameSet.Add(newName); + return; + } + } + + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniHumanoid/ForceUniqueName.cs.meta b/Assets/UniGLTF/Runtime/UniHumanoid/ForceUniqueName.cs.meta new file mode 100644 index 000000000..e0cbe042a --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniHumanoid/ForceUniqueName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51b5d93eece56c3449632c9ce0c4fc02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniHumanoid/HumanoidLoader.cs b/Assets/UniGLTF/Runtime/UniHumanoid/HumanoidLoader.cs index 0254e9943..45f0ec806 100644 --- a/Assets/UniGLTF/Runtime/UniHumanoid/HumanoidLoader.cs +++ b/Assets/UniGLTF/Runtime/UniHumanoid/HumanoidLoader.cs @@ -9,6 +9,8 @@ namespace UniHumanoid { public static Avatar LoadHumanoidAvatar(Transform root, IEnumerable<(Transform, HumanBodyBones)> boneMap) { + ForceUniqueName.Process(root); + var description = new HumanDescription { skeleton = root.GetComponentsInChildren()