はじめに
画像のように Collider のアタッチされた Prefab をリストアップします。
子 GameObject にアタッチされている場合は, Root の GameObject からのパスを表示します。
ソースコード
public class ColliderListWindow : ComponentListWindow<Collider> { [MenuItem("EditorWindow/ColliderListWindow")] private static void Init() { var window = GetWindow(typeof(ColliderListWindow)); window.titleContent = new GUIContent(nameof(ColliderListWindow)); window.Show(); window.minSize = new Vector2(330, 400); } } public class ComponentListWindow<T> : EditorWindow where T : Component { private SingleTreeView m_TreeView; private TreeViewState m_TreeViewState; private List<UnityObjectModel> m_ModelList = new(); private void OnEnable() { m_TreeViewState = new TreeViewState(); m_TreeView = new SingleTreeView(m_TreeViewState); if (m_ModelList.Count == 0) { m_ModelList.Add(UnityObjectModelFactory.instance.CreateEmpty()); } m_TreeView.Setup(m_ModelList); } private void OnGUI() { if (GUILayout.Button("実行")) { m_ModelList.Clear(); var paths = AssetDatabase.FindAssets("a: assets t:Prefab") .Select(guid => AssetDatabase.GUIDToAssetPath(guid)) .ToList(); for (int i = 0; i < paths.Count(); i++) { var path = paths[i]; var asset = AssetDatabase.LoadAssetAtPath<GameObject>(path); foreach (var child in asset.GetComponentsInChildren<T>()) { var name = GetPath(child.transform); var model = UnityObjectModelFactory.instance.CreateModel(name, child); m_ModelList.Add(model); } } m_TreeView.Setup(m_ModelList); } var rect = EditorGUILayout.GetControlRect(false, GUILayout.ExpandHeight(true)); m_TreeView.OnGUI(rect); } public static string GetPath(Transform transform) { var result = transform.name; var parent = transform.parent; while (parent != null) { result = parent.name + "/" + result; parent = parent.parent; } return result; } } public class SingleTreeView : TreeView { private List<UnityObjectModel> m_ModelList; public SingleTreeView(TreeViewState treeViewState) : base(treeViewState) { showAlternatingRowBackgrounds = true; } public void Setup(List<UnityObjectModel> modelList) { m_ModelList = modelList; Reload(); } protected override TreeViewItem BuildRoot() { var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; foreach (var model in m_ModelList) { var baseItem = new TreeViewItem { id = model.Id, displayName = model.Name, icon = model.Icon }; root.AddChild(baseItem); } SetupDepthsFromParentsAndChildren(root); return root; } } public class UnityObjectModelFactory : ScriptableSingleton<UnityObjectModelFactory> { [SerializeField] private int m_IdCounter; public UnityObjectModel CreateModel(string name, Object unityObject) { m_IdCounter++; var model = new UnityObjectModel(m_IdCounter, name, unityObject); return model; } public UnityObjectModel CreateEmpty() { m_IdCounter++; return new UnityObjectModel(m_IdCounter, "なし", null); } } public class UnityObjectModel { private int m_Id; private string m_Name; private List<UnityObjectModel> m_Children = new(); private Object m_UnityObject; private Texture2D m_Icon; public int Id => m_Id; public string Name => m_Name; public Object UnityObject => m_UnityObject; public Texture2D Icon => m_Icon; public List<UnityObjectModel> Children => m_Children; public UnityObjectModel(int id, string name, Object unityObject) { m_Id = id; m_Name = name; m_UnityObject = unityObject; if (m_UnityObject != null) { m_Icon = (Texture2D)EditorGUIUtility.ObjectContent(m_UnityObject, m_UnityObject.GetType()).image; } } public void AddChild(UnityObjectModel singleTreeViewModel) => m_Children.Add(singleTreeViewModel); }