From 3b39a1b7a4b98b0625469388acfe7f1bec8a8e16 Mon Sep 17 00:00:00 2001 From: Onur Er Date: Sat, 7 Jun 2025 20:38:20 -0700 Subject: [PATCH 1/6] Implemented feedback feature for avatar bones. --- Editor/Scripts/GLTFImporterInspector.cs | 329 +++++++++++++++++------- 1 file changed, 242 insertions(+), 87 deletions(-) diff --git a/Editor/Scripts/GLTFImporterInspector.cs b/Editor/Scripts/GLTFImporterInspector.cs index 773a0a898..fd9d1a0d9 100644 --- a/Editor/Scripts/GLTFImporterInspector.cs +++ b/Editor/Scripts/GLTFImporterInspector.cs @@ -23,13 +23,87 @@ namespace UnityGLTF [CanEditMultipleObjects] internal class GLTFImporterInspector : UnityGLTFTabbedEditor { - private string[] _importNormalsNames; - - public override void OnEnable() + static Texture BoneAssignmentDotIcon; + static Texture BoneAssignmentDotFrameIcon; + static Texture BoneAssignmentDotFrameDottedIcon; + + static string[] boneGroupTabs = { "Body", "Head", "Left Hand", "Right Hand" }; + static new Dictionary boneGroups = new() + { + { "Hips", "Body" }, + { "Spine", "Body" }, + { "Chest", "Body" }, + { "UpperChest", "Body" }, + { "Neck", "Body" }, + { "LeftUpperLeg", "Body" }, + { "RightUpperLeg", "Body" }, + { "LeftLowerLeg", "Body" }, + { "RightLowerLeg", "Body" }, + { "LeftFoot", "Body" }, + { "RightFoot", "Body" }, + { "LeftToes", "Body" }, + { "RightToes", "Body" }, + { "LeftShoulder", "Body" }, + { "LeftUpperArm", "Body" }, + { "LeftLowerArm", "Body" }, + { "LeftHand", "Body" }, + { "RightShoulder", "Body" }, + { "RightUpperArm", "Body" }, + { "RightLowerArm", "Body" }, + { "RightHand", "Body" }, + + { "Head", "Head" }, + { "Jaw", "Head" }, + { "LeftEye", "Head" }, + { "RightEye", "Head" }, + + { "Left Thumb Proximal", "Left Hand" }, + { "Left Thumb Intermediate", "Left Hand" }, + { "Left Thumb Distal", "Left Hand" }, + { "Left Index Proximal", "Left Hand" }, + { "Left Index Intermediate", "Left Hand" }, + { "Left Index Distal", "Left Hand" }, + { "Left Middle Proximal", "Left Hand" }, + { "Left Middle Intermediate", "Left Hand" }, + { "Left Middle Distal", "Left Hand" }, + { "Left Ring Proximal", "Left Hand" }, + { "Left Ring Intermediate", "Left Hand" }, + { "Left Ring Distal", "Left Hand" }, + { "Left Little Proximal", "Left Hand" }, + { "Left Little Intermediate", "Left Hand" }, + { "Left Little Distal", "Left Hand" }, + + { "Right Thumb Proximal", "Right Hand" }, + { "Right Thumb Intermediate", "Right Hand" }, + { "Right Thumb Distal", "Right Hand" }, + { "Right Index Proximal", "Right Hand" }, + { "Right Index Intermediate", "Right Hand" }, + { "Right Index Distal", "Right Hand" }, + { "Right Middle Proximal", "Right Hand" }, + { "Right Middle Intermediate", "Right Hand" }, + { "Right Middle Distal", "Right Hand" }, + { "Right Ring Proximal", "Right Hand" }, + { "Right Ring Intermediate", "Right Hand" }, + { "Right Ring Distal", "Right Hand" }, + { "Right Little Proximal", "Right Hand" }, + { "Right Little Intermediate", "Right Hand" }, + { "Right Little Distal", "Right Hand" }, + }; + + private string[] _importNormalsNames; + GLTFImporter importer; + readonly Dictionary boneTransforms = new(); + readonly Dictionary assignedBoneNames = new(); + Avatar avatar; + int selectedBoneGroupTab = 0; + + public override void OnEnable() { if (!this) return; - var m_HasSceneData = serializedObject.FindProperty(nameof(GLTFImporter.m_HasSceneData)); + importer = target as GLTFImporter; + + var m_HasSceneData = serializedObject.FindProperty(nameof(GLTFImporter.m_HasSceneData)); if (m_HasSceneData.boolValue) AddTab(new GLTFAssetImporterTab(this, "Model", ModelInspectorGUI)); @@ -43,34 +117,63 @@ public override void OnEnable() AddTab(new GLTFAssetImporterTab(this, "Extensions", ExtensionInspectorGUI)); AddTab(new GLTFAssetImporterTab(this, "Info", AssetInfoInspectorGUI)); - base.OnEnable(); + BoneAssignmentDotIcon = (Texture)EditorGUIUtility.Load("DotFill"); + BoneAssignmentDotFrameIcon = (Texture)EditorGUIUtility.Load("DotFrame"); + BoneAssignmentDotFrameDottedIcon = (Texture)EditorGUIUtility.Load("DotFrameDotted"); + + var animationMethod = serializedObject.FindProperty(nameof(GLTFImporter._importAnimations)); + if (animationMethod.enumValueIndex == (int)AnimationMethod.MecanimHumanoid) + { + avatar = AssetDatabase.LoadAssetAtPath(importer.assetPath); + + if (avatar && avatar.isHuman && avatar.isValid) PopulateBoneInfo(); + } + + base.OnEnable(); } - public override void OnInspectorGUI() + void PopulateBoneInfo() + { + var modelAsset = AssetDatabase.LoadAssetAtPath(importer.assetPath); + boneTransforms.Clear(); + + if (modelAsset) + { + foreach (var transform in modelAsset.GetComponentsInChildren(true)) + { + boneTransforms[transform.name] = transform; + } + + foreach (var bone in avatar.humanDescription.human) + { + assignedBoneNames[bone.humanName] = bone.boneName; + } + } + } + + public override void OnInspectorGUI() { - var t = target as GLTFImporter; - TextureWarningsGUI(t); + TextureWarningsGUI(); EditorGUILayout.Space(); base.OnInspectorGUI(); } - private void TextureWarningsGUI(GLTFImporter t) + private void TextureWarningsGUI() { - if (!t) return; - if (!GLTFImporterHelper.TextureImportSettingsAreCorrect(t)) + if (!importer) return; + if (!GLTFImporterHelper.TextureImportSettingsAreCorrect(importer)) { EditorGUILayout.HelpBox("Some Textures have incorrect linear/sRGB settings. Results might be incorrect.", MessageType.Warning); if (GUILayout.Button("Fix All")) { - GLTFImporterHelper.FixTextureImportSettings(t); + GLTFImporterHelper.FixTextureImportSettings(importer); } } } private void ModelInspectorGUI() { - var t = target as GLTFImporter; - if (!t) return; + if (!importer) return; // serializedObject.Update(); if (_importNormalsNames == null) @@ -91,7 +194,7 @@ private void ModelInspectorGUI() EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(GLTFImporter._readWriteEnabled)), new GUIContent("Read/Write")); #pragma warning disable 0618 - if (t._generateColliders) + if (importer._generateColliders) { serializedObject.FindProperty(nameof(GLTFImporter._addColliders)).enumValueIndex = (int)GLTFSceneImporter.ColliderType.Mesh; @@ -143,59 +246,113 @@ private bool EnableTextureRemapping } private static readonly GUIContent RemapTexturesToggleContent = new GUIContent("Experimental", "(experimental) Remap textures inside the glTF to textures that are already in your project."); - private void AnimationInspectorGUI() - { - var t = target as GLTFImporter; - if (!t) return; - - var hasAnimationData = serializedObject.FindProperty(nameof(GLTFImporter.m_HasAnimationData)).boolValue; - - if (!hasAnimationData) - { - EditorGUILayout.HelpBox("File doesn't contain animation data.", MessageType.None); - } - - var anim = serializedObject.FindProperty(nameof(GLTFImporter._importAnimations)); - EditorGUILayout.PropertyField(anim, new GUIContent("Animation Type")); - if (anim.enumValueIndex == (int)AnimationMethod.MecanimHumanoid) - { - var flip = serializedObject.FindProperty(nameof(GLTFImporter._mecanimHumanoidFlip)); - EditorGUI.indentLevel++; - EditorGUILayout.PropertyField(flip, new GUIContent("Flip Forward", "Some formats like VRM have a different forward direction for Avatars. Enable this option if the animation looks inverted.")); - EditorGUI.indentLevel--; - } - if (hasAnimationData && anim.enumValueIndex > 0) - { - var loopTime = serializedObject.FindProperty(nameof(GLTFImporter._animationLoopTime)); - EditorGUILayout.PropertyField(loopTime, new GUIContent("Loop Time")); - if (loopTime.boolValue) - { - EditorGUI.indentLevel++; - EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(GLTFImporter._animationLoopPose)), new GUIContent("Loop Pose")); - EditorGUI.indentLevel--; - } - } - - // show animations for clip import editing - var animations = serializedObject.FindProperty("m_Animations"); - if (animations.arraySize > 0) - { - EditorGUILayout.Space(); - EditorGUILayout.PropertyField(animations, new GUIContent("Animations"), true); - } - - // warn if Humanoid rig import has failed - if (!HasModified() && anim.enumValueIndex == (int) AnimationMethod.MecanimHumanoid && !AssetDatabase.LoadAssetAtPath(t.assetPath)) - { - EditorGUILayout.Separator(); - EditorGUILayout.HelpBox("The model doesn't contain a valid Humanoid rig. See the console for more information.", MessageType.Error); - } - } + private void AnimationInspectorGUI() + { + if (!importer) return; + + var hasAnimationData = serializedObject.FindProperty(nameof(GLTFImporter.m_HasAnimationData)).boolValue; + + if (!hasAnimationData) + { + EditorGUILayout.HelpBox("File doesn't contain animation data.", MessageType.None); + } + + var animationMethod = serializedObject.FindProperty(nameof(GLTFImporter._importAnimations)); + EditorGUILayout.PropertyField(animationMethod, new GUIContent("Animation Type")); + if (animationMethod.enumValueIndex == (int)AnimationMethod.MecanimHumanoid) + { + var flip = serializedObject.FindProperty(nameof(GLTFImporter._mecanimHumanoidFlip)); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(flip, new GUIContent("Flip Forward", "Some formats like VRM have a different forward direction for Avatars. Enable this option if the animation looks inverted.")); + EditorGUI.indentLevel--; + } + if (hasAnimationData && animationMethod.enumValueIndex > 0) + { + var loopTime = serializedObject.FindProperty(nameof(GLTFImporter._animationLoopTime)); + EditorGUILayout.PropertyField(loopTime, new GUIContent("Loop Time")); + if (loopTime.boolValue) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(GLTFImporter._animationLoopPose)), new GUIContent("Loop Pose")); + EditorGUI.indentLevel--; + } + } + + // show animations for clip import editing + var animations = serializedObject.FindProperty("m_Animations"); + if (animations.arraySize > 0) + { + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(animations, new GUIContent("Animations"), true); + } + + if (animationMethod.enumValueIndex == (int)AnimationMethod.MecanimHumanoid) + { + // List all bones and any assigned gameobjects. + if (avatar && avatar.isHuman && avatar.isValid) + { + var humanBones = avatar.humanDescription.human; + var allMecanimBonesCount = HumanTrait.BoneName.Length; + EditorGUILayout.Separator(); + EditorGUILayout.LabelField("Avatar Bones", EditorStyles.boldLabel); + EditorGUILayout.LabelField("Assigned Bones:", humanBones.Length + "/" + allMecanimBonesCount); + + EditorGUILayout.BeginHorizontal(); + var legendIconRect = GUILayoutUtility.GetRect(18, 18, GUILayout.Width(18), GUILayout.Height(18)); + GUI.DrawTexture(legendIconRect, BoneAssignmentDotFrameDottedIcon, ScaleMode.ScaleToFit, true); + GUILayout.Label("Optional bone", EditorStyles.miniLabel); + EditorGUILayout.EndHorizontal(); + + selectedBoneGroupTab = GUILayout.Toolbar(selectedBoneGroupTab, boneGroupTabs); + + EditorGUI.indentLevel++; + + for (var i = 0; i < allMecanimBonesCount; i++) + { + var MecanimBoneName = HumanTrait.BoneName[i]; + if (boneGroupTabs[selectedBoneGroupTab] != boneGroups[MecanimBoneName]) continue; + + assignedBoneNames.TryGetValue(MecanimBoneName, out string assignedBoneName); + Transform transform = null; + if (!string.IsNullOrEmpty(assignedBoneName)) + { + boneTransforms.TryGetValue(assignedBoneName, out transform); + } + + EditorGUILayout.BeginHorizontal(); + + var iconRect = GUILayoutUtility.GetRect(18, 18, GUILayout.Width(18), GUILayout.Height(18)); + var frameIcon = HumanTrait.RequiredBone(i) ? BoneAssignmentDotFrameIcon : BoneAssignmentDotFrameDottedIcon; + + if (transform) + { + var originalColor = GUI.color; + GUI.color = Color.green; + GUI.DrawTexture(iconRect, frameIcon, ScaleMode.ScaleToFit, true); + GUI.DrawTexture(iconRect, BoneAssignmentDotIcon, ScaleMode.ScaleToFit, true); + GUI.color = originalColor; + } + else GUI.DrawTexture(iconRect, frameIcon, ScaleMode.ScaleToFit, true); + + GUILayout.Label(MecanimBoneName, GUILayout.Width(130)); + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.ObjectField(transform, typeof(Transform), true); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.EndHorizontal(); + } + + EditorGUI.indentLevel--; + } + // warn if Humanoid rig import has failed + else EditorGUILayout.HelpBox("The model doesn't contain a valid Humanoid rig. See the console for more information.", MessageType.Error); + } + } private void MaterialInspectorGUI() { - var t = target as GLTFImporter; - if (!t) return; + if (!importer) return; var importMaterialsProp = serializedObject.FindProperty(nameof(GLTFImporter._importMaterials)); EditorGUILayout.PropertyField(importMaterialsProp); @@ -210,7 +367,7 @@ private void MaterialInspectorGUI() var importedMaterials = serializedObject.FindProperty("m_Materials"); if (importedMaterials.arraySize > 0) { - RemappingUI(t, importedMaterials, "Materials", ".mat"); + RemappingUI(importedMaterials, "Materials", ".mat"); } // There's a bunch of known edge cases with texture remapping that can go wrong, @@ -221,7 +378,7 @@ private void MaterialInspectorGUI() var importedTextures = serializedObject.FindProperty("m_Textures"); if (EnableTextureRemapping && importedTextures.arraySize > 0) { - RemappingUI(t, importedTextures, "Textures", ".asset"); + RemappingUI(importedTextures, "Textures", ".asset"); } var identifierProp = serializedObject.FindProperty(nameof(GLTFImporter._useSceneNameIdentifier)); @@ -252,14 +409,14 @@ private void MaterialInspectorGUI() EditorGUILayout.Separator(); } - private void RemappingUI(GLTFImporter t, SerializedProperty importedData, string subDirectoryName, string fileExtension) where T: UnityEngine.Object + private void RemappingUI(SerializedProperty importedData, string subDirectoryName, string fileExtension) where T: UnityEngine.Object { // extract and remap materials if (importedData != null && importedData.serializedObject != null) { EditorGUI.indentLevel++; - var externalObjectMap = t.GetExternalObjectMap(); + var externalObjectMap = importer.GetExternalObjectMap(); // TODO this also counts old remaps that are not used anymore var remapCount = externalObjectMap.Values.Count(x => x is T); @@ -267,7 +424,7 @@ void ExtractAsset(T subAsset, bool importImmediately) { if (!subAsset) return; var filename = SanitizePath(subAsset.name); - var dirName = Path.GetDirectoryName(t.assetPath) + "/" + subDirectoryName; + var dirName = Path.GetDirectoryName(importer.assetPath) + "/" + subDirectoryName; if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName); var destinationPath = dirName + "/" + filename + fileExtension; @@ -301,14 +458,14 @@ void ExtractAsset(T subAsset, bool importImmediately) { var mat = importedData.GetArrayElementAtIndex(i).objectReferenceValue as T; if (!mat) continue; - t.RemoveRemap(new AssetImporter.SourceAssetIdentifier(mat)); + importer.RemoveRemap(new AssetImporter.SourceAssetIdentifier(mat)); } // also remove all old remaps var oldRemaps = externalObjectMap.Where(x => x.Value is T).ToList(); foreach (var oldRemap in oldRemaps) { - t.RemoveRemap(oldRemap.Key); + importer.RemoveRemap(oldRemap.Key); } } @@ -346,9 +503,9 @@ void ExtractAsset(T subAsset, bool importImmediately) if (EditorGUI.EndChangeCheck()) { if (newObj && newObj != mat) - t.AddRemap(id, newObj); + importer.AddRemap(id, newObj); else - t.RemoveRemap(id); + importer.RemoveRemap(id); } if (!remap) @@ -363,7 +520,7 @@ void ExtractAsset(T subAsset, bool importImmediately) { if (GUILayout.Button("Restore", GUILayout.Width(60))) { - t.RemoveRemap(id); + importer.RemoveRemap(id); #if UNITY_2022_2_OR_NEWER SaveChanges(); #else @@ -387,8 +544,7 @@ void ExtractAsset(T subAsset, bool importImmediately) private static GUIStyle _richTextWordWrap; private void AssetInfoInspectorGUI() { - var t = target as GLTFImporter; - if (!t) return; + if (!importer) return; var assetProp = serializedObject.FindProperty(nameof(GLTFImporter._gltfAsset)); if (assetProp == null) return; @@ -401,15 +557,15 @@ private void AssetInfoInspectorGUI() _richTextWordWrap = style; } - if (string.IsNullOrEmpty(t._gltfAsset)) + if (string.IsNullOrEmpty(importer._gltfAsset)) { EditorGUILayout.LabelField("No asset information included in file", _richTextWordWrap); return; } EditorGUILayout.Space(); - var rect = GUILayoutUtility.GetRect(new GUIContent(t._gltfAsset), _richTextWordWrap); - EditorGUI.SelectableLabel(rect, t._gltfAsset, _richTextWordWrap); + var rect = GUILayoutUtility.GetRect(new GUIContent(importer._gltfAsset), _richTextWordWrap); + EditorGUI.SelectableLabel(rect, importer._gltfAsset, _richTextWordWrap); EditorGUILayout.Space(); EditorGUI.BeginDisabledGroup(true); @@ -419,8 +575,7 @@ private void AssetInfoInspectorGUI() private void ExtensionInspectorGUI() { - var t = target as GLTFImporter; - if (!t) return; + if (!importer) return; EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(GLTFImporter._extensions)), new GUIContent("Extensions in file")); EditorGUI.EndDisabledGroup(); @@ -428,7 +583,7 @@ private void ExtensionInspectorGUI() // TODO add list of supported extensions and links to docs // Gather list of all plugins var registeredPlugins = GLTFSettings.GetDefaultSettings().ImportPlugins; - var overridePlugins = t._importPlugins; + var overridePlugins = importer._importPlugins; EditorGUILayout.Space(); EditorGUILayout.LabelField("Available Import Plugins", EditorStyles.boldLabel); @@ -472,10 +627,10 @@ private void ExtensionInspectorGUI() overrideEnabled = true, }; overridePlugin = newPlugin; - t._importPlugins.Add(newPlugin); + importer._importPlugins.Add(newPlugin); } } - EditorUtility.SetDirty(t); + EditorUtility.SetDirty(importer); } EditorGUI.BeginDisabledGroup(!hasOverride); var currentlyEnabled = (overridePlugin != null && overridePlugin.overrideEnabled) ? overridePlugin.enabled : plugin.EnabledByDefault; @@ -484,7 +639,7 @@ private void ExtensionInspectorGUI() { currentlyEnabled = enabled; overridePlugin.enabled = enabled; - EditorUtility.SetDirty(t); + EditorUtility.SetDirty(importer); } EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup(false); @@ -494,7 +649,7 @@ private void ExtensionInspectorGUI() EditorGUILayout.EndHorizontal(); // This assumes that the display name of a Plugin matches what extension it operates on. // It's not correct for Plugins that operate on multiple extensions, or none at all. - if (hasWarning && t._extensions?.Find(x => x.name == plugin.DisplayName) != null) + if (hasWarning && importer._extensions?.Find(x => x.name == plugin.DisplayName) != null) { EditorGUILayout.HelpBox(plugin.Warning, MessageType.Warning); editorCache.TryGetValue(plugin.GetType(), out var editor); From 851f4fc06c68ccd39fd57f479817dd9f89d37e4a Mon Sep 17 00:00:00 2001 From: Onur Er Date: Sat, 7 Jun 2025 20:56:03 -0700 Subject: [PATCH 2/6] Fixed a capitalization. --- Editor/Scripts/GLTFImporterInspector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Editor/Scripts/GLTFImporterInspector.cs b/Editor/Scripts/GLTFImporterInspector.cs index fd9d1a0d9..779ebf065 100644 --- a/Editor/Scripts/GLTFImporterInspector.cs +++ b/Editor/Scripts/GLTFImporterInspector.cs @@ -300,7 +300,7 @@ private void AnimationInspectorGUI() EditorGUILayout.BeginHorizontal(); var legendIconRect = GUILayoutUtility.GetRect(18, 18, GUILayout.Width(18), GUILayout.Height(18)); GUI.DrawTexture(legendIconRect, BoneAssignmentDotFrameDottedIcon, ScaleMode.ScaleToFit, true); - GUILayout.Label("Optional bone", EditorStyles.miniLabel); + GUILayout.Label("Optional Bone", EditorStyles.miniLabel); EditorGUILayout.EndHorizontal(); selectedBoneGroupTab = GUILayout.Toolbar(selectedBoneGroupTab, boneGroupTabs); From 02344ab84866f68806608a759c2b9a0d7f238c26 Mon Sep 17 00:00:00 2001 From: Onur Er Date: Sun, 8 Jun 2025 17:39:52 -0700 Subject: [PATCH 3/6] Made avatar name compatible with FBX importer's behavior too. This makes finding the desired avatar in the project easier. --- Editor/Scripts/Internal/HumanoidSetup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Editor/Scripts/Internal/HumanoidSetup.cs b/Editor/Scripts/Internal/HumanoidSetup.cs index 76d950fcc..a93ac2e18 100644 --- a/Editor/Scripts/Internal/HumanoidSetup.cs +++ b/Editor/Scripts/Internal/HumanoidSetup.cs @@ -24,7 +24,7 @@ internal static Avatar AddAvatarToGameObject(GameObject gameObject, bool flipFor gameObject.transform.rotation *= Quaternion.Euler(0,180,0); Avatar avatar = AvatarBuilder.BuildHumanAvatar(gameObject, description); - avatar.name = "Avatar"; + avatar.name = gameObject.name+"Avatar"; if (flipForward) gameObject.transform.rotation = previousRotation; From e6e39d9a423a71d58022ed4951f53d653398c28a Mon Sep 17 00:00:00 2001 From: Onur Er Date: Sun, 8 Jun 2025 17:47:31 -0700 Subject: [PATCH 4/6] Fixed the var name. --- Editor/Scripts/GLTFImporterInspector.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Editor/Scripts/GLTFImporterInspector.cs b/Editor/Scripts/GLTFImporterInspector.cs index 779ebf065..b44d15928 100644 --- a/Editor/Scripts/GLTFImporterInspector.cs +++ b/Editor/Scripts/GLTFImporterInspector.cs @@ -309,10 +309,10 @@ private void AnimationInspectorGUI() for (var i = 0; i < allMecanimBonesCount; i++) { - var MecanimBoneName = HumanTrait.BoneName[i]; - if (boneGroupTabs[selectedBoneGroupTab] != boneGroups[MecanimBoneName]) continue; + var mecanimBoneName = HumanTrait.BoneName[i]; + if (boneGroupTabs[selectedBoneGroupTab] != boneGroups[mecanimBoneName]) continue; - assignedBoneNames.TryGetValue(MecanimBoneName, out string assignedBoneName); + assignedBoneNames.TryGetValue(mecanimBoneName, out string assignedBoneName); Transform transform = null; if (!string.IsNullOrEmpty(assignedBoneName)) { @@ -334,7 +334,7 @@ private void AnimationInspectorGUI() } else GUI.DrawTexture(iconRect, frameIcon, ScaleMode.ScaleToFit, true); - GUILayout.Label(MecanimBoneName, GUILayout.Width(130)); + GUILayout.Label(mecanimBoneName, GUILayout.Width(130)); EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField(transform, typeof(Transform), true); From 2d85776ffa964938ee87c862c6f60d152ede765d Mon Sep 17 00:00:00 2001 From: Onur Er Date: Sun, 8 Jun 2025 17:51:26 -0700 Subject: [PATCH 5/6] Added missing assignedBoneNames.Clear call. --- Editor/Scripts/GLTFImporterInspector.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Editor/Scripts/GLTFImporterInspector.cs b/Editor/Scripts/GLTFImporterInspector.cs index b44d15928..473094bd6 100644 --- a/Editor/Scripts/GLTFImporterInspector.cs +++ b/Editor/Scripts/GLTFImporterInspector.cs @@ -136,6 +136,7 @@ void PopulateBoneInfo() { var modelAsset = AssetDatabase.LoadAssetAtPath(importer.assetPath); boneTransforms.Clear(); + assignedBoneNames.Clear(); if (modelAsset) { From ab1b02cedba542814e5eb46172e6127c8744b88f Mon Sep 17 00:00:00 2001 From: Onur Er Date: Sun, 13 Jul 2025 10:29:56 -0700 Subject: [PATCH 6/6] Fixed a conflict caused by recent changes on official dev branch. --- Editor/Scripts/GLTFImporterInspector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Editor/Scripts/GLTFImporterInspector.cs b/Editor/Scripts/GLTFImporterInspector.cs index 9c06b31d9..ddadde8bd 100644 --- a/Editor/Scripts/GLTFImporterInspector.cs +++ b/Editor/Scripts/GLTFImporterInspector.cs @@ -429,7 +429,7 @@ void ExtractAssets(T[] subAssets, bool importImmediately) { if (!subAsset) return; var filename = SanitizePath(subAsset.name); - var dirName = Path.GetDirectoryName(t.assetPath) + "/" + subDirectoryName; + var dirName = Path.GetDirectoryName(importer.assetPath) + "/" + subDirectoryName; if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName); var destinationPath = dirName + "/" + filename + fileExtension;