Unity 怎么创建树形菜单

再网上找了很多方法都不行,bug很多……最主要的是自己不会用;
有没有那种简单的一看就会的
或者是调试完没有问题的
我的unity是2018.7.14

望采纳:
可以使用UnityEditor.EditorWindow类创建树形菜单
示例:

using UnityEngine;
using UnityEditor;

public class TreeViewEditorWindow : EditorWindow
{
    private TreeView treeView;

    [MenuItem("Window/Tree View Example")]
    private static void OpenWindow()
    {
        GetWindow<TreeViewEditorWindow>();
    }

    private void OnEnable()
    {
        treeView = new TreeView();
    }

    private void OnGUI()
    {
        treeView.OnGUI(new Rect(0, 0, position.width, position.height));
    }
}


你可以使用Unity's UI System创建树形菜单。下面是一个大致的步骤:

1.创建一个Canvas,然后创建一个Text作为菜单的标题。

2.创建一个Empty GameObject,作为菜单的父节点。

3.添加一个Layout Group组件到父节点,并将它的类型设置为Vertical Layout Group。

4.创建一个新的Text GameObject作为子节点,挂载到父节点下。

5.重复步骤4,直到您创建了足够的子节点来创建树形结构。

6.设置好合适的边距,使得每个子节点的位置彼此分离。

7.使用代码实现打开和关闭菜单的逻辑。

可以使用Unity自带的IMGUI(Inspector and Editor GUI)系统创建树形菜单。步骤如下:

1.在Unity Editor中创建脚本并编写树形菜单代码;
2.在Unity场景中添加脚本到游戏物体上;
3.在脚本的OnInspectorGUI方法中绘制菜单;
4.在Inspector窗口中查看结果。
代码示例:

using UnityEngine;
using UnityEditor;

public class TreeMenuExample : MonoBehaviour
{
    public int selectedOption;
    public string[] options = new string[] {"Option 1", "Option 2", "Option 3"};

    private void OnInspectorGUI()
    {
        selectedOption = EditorGUILayout.Popup("Options", selectedOption, options);
    }
}


可以使用 Unity 自带的 UI 系统创建树形菜单:

1.在 Scene 视图中创建一个 UI 面板
2.在面板上添加一个 Scroll View 组件,并调整其大小以适应所有节点
3.在 Scroll View 内部创建一个空的 GameObject,并命名为 Content
4.把 Content 设置为 Scroll View 的 Content
5.在 Content 下添加多个空的 GameObject,并使用 UI 元素(例如 Button 和 Text)将它们转换为菜单节点
6.使用代码或 UI 系统的交互功能,在节点之间创建父子关系
7.根据需要,可以为节点添加点击事件,并显示或隐藏子节点
如果不会代码的话可以利用 Unity Asset Store 中的第三方 UI 插件创建树形菜单。

这是一个完整的树形菜单代码实现示例,使用 C# 语言:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TreeView : MonoBehaviour
{
    public GameObject nodePrefab; // 节点预制件
    public Transform content; // Scroll View 的 Content

    private List<TreeNode> allNodes = new List<TreeNode>(); // 所有节点列表

    // 创建树形菜单
    public void CreateTree(TreeNode node)
    {
        allNodes.Clear();
        GetAllNodes(node);
        content.DestroyChildren();

        foreach (var n in allNodes)
        {
            if (n.parent == null || n.parent.isExpanded)
            {
                var newNode = Instantiate(nodePrefab, content);
                newNode.GetComponentInChildren<Text>().text = n.value;

                // 给节点添加点击事件
                newNode.GetComponent<Button>().onClick.AddListener(() =>
                {
                    OnNodeClicked(n);
                });
            }
        }
    }

    // 获取所有节点
    private void GetAllNodes(TreeNode node)
    {
        allNodes.Add(node);
        foreach (var child in node.children)
        {
            GetAllNodes(child);
        }
    }

    // 节点点击事件处理
    private void OnNodeClicked(TreeNode node)
    {
        node.isExpanded = !node.isExpanded;
        CreateTree(node.parent == null ? node : node.parent);
    }

    // 树形节点数据结构
    public class TreeNode
    {
        public TreeNode parent;
        public List<TreeNode> children = new List<TreeNode>();
        public string value;
        public bool isExpanded;
    }

    // 销毁所有子节点
    private void DestroyChildren(Transform t)
    {
        foreach (Transform child in t)
        {
            Destroy(child.gameObject);
        }
    }
}

可以满足一般的树形菜单功能需求。可以根据具体需求进行更改和完善。
如果我的回答对您有帮助请及时采纳谢谢

参考一下https://blog.csdn.net/qq_33179161/article/details/88973464


using UnityEngine;

public class TreeMenu : MonoBehaviour
{
    public TreeNode rootNode;
    public int currentLevel;
    public TreeNode selectedNode;
    
    // Start is called before the first frame update
    void Start()
    {
        rootNode = new TreeNode(null, 0, "root");
        currentLevel = 0;
        selectedNode = rootNode;
    }

    // Update is called once per frame
    void Update()
    {
        // Do something here
    }

    public void AddNode(TreeNode parentNode, string name)
    {
        TreeNode newNode = new TreeNode(parentNode, parentNode.level + 1, name);
        parentNode.children.Add(newNode);
    }

    public void SelectNode(TreeNode node)
    {
        selectedNode = node;
        currentLevel = node.level;
    }
}

public class TreeNode
{
    public TreeNode parent;
    public List<TreeNode> children;
    public int level;
    public string name;

    public TreeNode(TreeNode parent, int level, string name)
    {
        this.parent = parent;
        this.children = new List<TreeNode>();
        this.level = level;
        this.name = name;
    }

}

。直接自己拼

一、首先,我们先制作子元素的模板(Template),也就是图中菜单的单个元素,用它来根据数据源动态克隆出多个子元素。
二、我们的每个子元素都会携带一个TreeViewItem脚本,用于描述自身在整个树形菜单中与其他元素的父子关系,而整个树形菜单的控制由TreeViewControl来实现,首先,TreeViewControl会根据提供的数据源来生成所有的子元素,当然,改变数据源之后进行重新生成的时候也是这个方法,干的事情很简单,就是用模板不停的创建元素,并给他们建立父子关系。
三、树形菜单生成完毕之后此时所有元素虽然都记录了自身与其他元素的父子关系,但他们的位置都是在Vector3.zero的,毕竟我们的菜单元素在创建的时候都是一股脑儿的丢到原点位置的,创建君可不管这么多元素挤在一堆会不会憋死,好吧,之后规整列队的事情就交给刷新君来完成了,刷新君玩的一手好递归,它会遍历所有元素并剔除不可见的元素(也就是点击三角按钮隐藏了),并将它们一个一个的重新排列整齐,子排在父之后,孙排在子之后,以此类推......它会遍历每个元素的子元素列表,发现子元素可见便进入子元素列表,发现孙元素可见便进入孙元素列表。
四、菜单已经创建完毕并且经过了一轮刷新,此时它展示出来的就是这样一个所有子元素都展开的形状(我在demo中指定了数据源,关于数据源怎么设置在后面)