具有层次结构的自定义窗口

本文关键字:自定义 窗口 层次结构 | 更新日期: 2023-09-27 18:31:09

我正在构建一个自定义窗口,我想模仿Unity的层次结构并将其添加到我的窗口中。

这是我到目前为止所拥有的,我不想做的是像在 Unity 编辑器中一样将子对象和父对象分组在一起。目前,它只是将场景中的每个对象列为没有子项的列表。如何让它看起来像 Unity 的层次结构视图?

void OnGUI() {
    EditorGUILayout.BeginHorizontal(); 
    {
        scroll = EditorGUILayout.BeginScrollView(scroll, GUILayout.Width(200), GUILayout.Height(500));
        {
            GameObject[] gameObjects = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[];
            foreach (GameObject go in gameObjects) {
                EditorGUILayout.Foldout(false, go.name);
            }
        }
        EditorGUILayout.EndScrollView();
    }
    EditorGUILayout.EndHorizontal();
}

具有层次结构的自定义窗口

你可以做这样的事情:

void OnGUI() {
    EditorGUILayout.BeginHorizontal();
    {
        scroll = EditorGUILayout.BeginScrollView(scroll, GUILayout.Width(200), GUILayout.Height(500));
        {
            GameObject[] gameObjects = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[];
            foreach (GameObject go in gameObjects) {
                // Start with game objects without any parents
                if (go.transform.parent == null) {
                    // Show the object and its children
                    ShowObject(go, gameObjects);
                }
            }
        }
        EditorGUILayout.EndScrollView();
    }
    EditorGUILayout.EndHorizontal();
}
void ShowObject(GameObject parent, GameObject[] gameObjects) {
    // Show entry for parent object
    if (UnityEditor.EditorGUILayout.Foldout(IsEntryOpen(parent), parent.name)) {
        foreach (GameObject go in gameObjects) {
            // Find children of the parent game object
            if (go.transform.parent == parent.transform) {
                ShowObject(go, gameObjects);
            }
        }
    }
}

请注意,您还需要一种方法来跟踪打开的对象条目(实现 IsEntryOpen() 方法)。为此,您可以有一个列表,如果 Foldout() 返回 true,则将游戏对象添加到此列表中,如果返回 false,则删除。

您还需要以某种方式缩进子对象。一种方法是将它们包裹在GUILayout.BeginHorizontal()GUILayout.BeginVertical()中,并使用GUILayout.Space()缩进。