using UnityEngine; using UnityEditor; using System.Collections.Generic; public class FindUnusedBones : EditorWindow { private List excludeStrings = new List(); // 제외할 문자열 리스트 [MenuItem("Tools/Bone Tools/Find Unused Bones")] public static void ShowWindow() { GetWindow("Find Unused Bones"); } private void OnGUI() { GUILayout.Label("Exclude Strings", EditorStyles.boldLabel); // 동적으로 문자열 입력 필드와 + - 버튼을 추가 for (int i = 0; i < excludeStrings.Count; i++) { GUILayout.BeginHorizontal(); excludeStrings[i] = EditorGUILayout.TextField($"Exclude String {i + 1}", excludeStrings[i]); if (GUILayout.Button("-", GUILayout.Width(20))) { excludeStrings.RemoveAt(i); } GUILayout.EndHorizontal(); } if (GUILayout.Button("+", GUILayout.Width(20))) { excludeStrings.Add(string.Empty); // 빈 문자열 입력 필드 추가 } GUILayout.Space(20); if (GUILayout.Button("Find and Select Unused Bones")) { FindAndSelectUnusedBones(); } } private void FindAndSelectUnusedBones() { if (Selection.activeGameObject == null) { Debug.LogWarning("No GameObject selected!"); return; } Transform root = Selection.activeGameObject.transform; SkinnedMeshRenderer[] skinnedMeshRenderers = root.GetComponentsInChildren(); HashSet usedBones = new HashSet(); HashSet excludedObjects = new HashSet(); // Add all bones used by SkinnedMeshRenderers to usedBones set foreach (var skinnedMeshRenderer in skinnedMeshRenderers) { foreach (var bone in skinnedMeshRenderer.bones) { usedBones.Add(bone); } // Add the SkinnedMeshRenderer's gameObject and its parents to excludedObjects set Transform current = skinnedMeshRenderer.transform; while (current != null) { excludedObjects.Add(current); current = current.parent; } } List unusedBones = new List(); Transform[] allBones = root.GetComponentsInChildren(); foreach (var bone in allBones) { // 문자열 필터링: 사용자가 입력한 문자열을 포함한 오브젝트는 제외 bool excludeBone = false; foreach (var excludeString in excludeStrings) { if (!string.IsNullOrEmpty(excludeString) && bone.name.ToLower().Contains(excludeString.ToLower())) { excludeBone = true; break; } } if (!usedBones.Contains(bone) && !excludedObjects.Contains(bone) && bone != root && !excludeBone) // 필터링된 오브젝트 제외 { unusedBones.Add(bone); } } if (unusedBones.Count > 0) { Selection.objects = unusedBones.ConvertAll(b => b.gameObject).ToArray(); Debug.Log($"Found {unusedBones.Count} unused bones. Selected in the hierarchy."); } else { Debug.Log("No unused bones found."); } } }