Unity菜单树 TreeView

今天说一下读取Json文件,生成菜单树。
菜单树可以直接去Asset Store搜索TreeView,下载免费的那个
就是这个

那么拿到菜单树之后,怎么将Json数据植入到我菜单树里面呢?
这就需要我们对Json文件做一些处理了。
既然称之为树,那么深度肯定是必不可少的东西,以根节点深度0为基准,子节点深度为1,孙节点深度为2等。知道了每个节点的深度,还得知道父节点是谁,否则就是某个孙子知道自己有爷爷,但是不知道自己爷爷是谁了。
有了父子关系和深度,那么就好办了
首先根据Json数据计算出最大深度,这决定了我们要创建多少级菜单。
直接上代码:

	public struct MenuTree
	{
	    public string name;
	    public string type;
	    public float id;
	    public float depth;
	    public float parentId;
	    public Color color;
	    public string info;
	    public string state;
	    public string equipment;
	    public string component;
	    public FaultItem[] faultItem;
	}
	
    public static MenuTree[] LoadMenuTreeData(JsonData jd)
    {
        menuTreeDatas = new MenuTree[jd.Count];
        for (int i = 0; i < jd.Count; i++)
        {
            faultItems = new FaultItem[jd[i]["faultItem"].Count];
            for (int j = 0; j < jd[i]["faultItem"].Count; j++)
            {
                faultItems[j].faultName = jd[i]["faultItem"][j]["faultName"].ToString();
                faultItems[j].faultId =int.Parse(jd[i]["faultItem"][j]["faultId"].ToString());
            }

            menuTreeDatas[i].name = jd[i]["name"].ToString().TrimEnd();
            menuTreeDatas[i].type = jd[i]["type"].ToString().TrimEnd();
            menuTreeDatas[i].id = float.Parse(jd[i]["id"].ToString());
            menuTreeDatas[i].depth = float.Parse(jd[i]["depth"].ToString());
            menuTreeDatas[i].parentId = float.Parse(jd[i]["parentId"].ToString());
            menuTreeDatas[i].info = jd[i]["info"].ToString();
            menuTreeDatas[i].state = jd[i]["state"].ToString();
            menuTreeDatas[i].equipment = jd[i]["equipment"].ToString();
            menuTreeDatas[i].faultItem = faultItems;
        }
        return menuTreeDatas;
    }
    
    public static MenuTree[] LoadLocalMenuTree()
    {
        string ta = File.ReadAllText(Application.streamingAssetsPath + "/MenuTree.json");
        JsonData jd = JsonMapper.ToObject(ta.ToString());
        menuTreeDatas = LoadMenuTreeData(jd);
        return menuTreeDatas;
    }
    
    public static float GetMaxDepth()
    {
        MenuTree[] tmp = DataHandler.LoadLocalMenuTree();
        float maxDepth = tmp[0].depth;

        for (int i = 1; i < CV_DataHandler.LoadLocalMenuTree().Length; i++)
        {
            if (maxDepth < tmp[i].depth)
                maxDepth = tmp[i].depth;
        }

        return maxDepth;
    }

好的,获取到了最大深度,那么我们就可以大刀阔斧地干了,直接找到导入的Example脚本,挂载在空物体上,然后再添加TreeViewControl脚本,把所有你能看到的ParentControl变量都拖上去,然后修改Example脚本的PopulateExampleData方法:

 public static void PopulateExampleData(TreeViewControl item)
    {
        MenuTree[] tmp = DataHandler.LoadLocalMenuTree();
        item.Width = 260;
        item.Height = 1000;
        item.Header = "-1节点";//根节点的父节点,也可以直接作为根节点

        List<MenuTree> menuTree = tmp.ToList();
        float dep = DataHandler.GetMaxDepth();
        for (int i = 0; i <= dep; i++)
        {
            foreach (var it in menuTree)
            {
                if (it.depth.Equals(i))
                {
                    TreeViewItem tvitem = new TreeViewItem(null, null);//生成新的菜单项
                    float pd = it.parentId;//父物体ID
                    string _name = it.name;
                    if (pd < 0)//根节点没有父物体,父物体ID小于0就行
                        tvitem = item.RootItem.AddItem(_name);
                    else
                        tvitem = treeViewItemList.Find(x => x.ID.Equals(pd)).AddItem(_name);
                    tvitem.ID = it.id;
                    tvitem.equipmentName = it.equipment;
                    tvitem.myName = it.name;
                    AddEvents(tvitem);
                    treeViewItemList.Add(tvitem);
                    addName.Add(_name);

                }
            }
        }
    }

于是我们就能得到我们想要的效果了,其中TreeViewItem可以添加自己想要存储的变量,点击的时候可以获取这些变量。
当我们敲代码的时候遇到某些逻辑问题难以捋清的时候,不妨试一试通过伪代码,或者直接一行一行先用文字述清每一步的逻辑,再回过头来,事情也许就能变的简单很多。
周更,迟交一天,罪过

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Unity自带的菜单选项可以为开发人员提供快捷的功能,但是当我们需要一个更加专业化的菜单时,Unity的默认菜单选项可能无法满足需求。此时,自定义菜单就应运而生。 Unity的自定义菜单是基于EditorGUILayout的GUI实现的。首先,我们需要扩展Editor类并使用MenuCommand属性,以及EditorGUI类,来为自定义菜单添加菜单项和功能选项。然后,我们可以使用GUILayout实现垂直排列的菜单,在每个菜单项的后面添加子菜单。 接下来,我们应该为自定义菜单添加相应的功能。在每个菜单项中,我们可以通过EditorGUILayout实现按钮、文本框、下拉菜单等等,为每个功能选项设计对应的功能。比如,我们可以在菜单项中添加新的对象、展开/折叠所有对象、删除特定的对象等功能。 最后,我们需要重写OnGUI方法,在其中调用自己的菜单绘制函数。这样,在编辑器中打开自定义窗口时,我们就可以看到新的菜单和功能选项了。另外,我们要记得在Menu选项中添加自定义的扩展菜单,这样才能在编辑器菜单中添加自己的菜单项。 总而言之,Unity的自定义菜单功能可以让开发人员更加简便地实现自己的的菜单和功能选项。如果你想为Unity添加一些自定义的、专业化的菜单和功能选项,自定义菜单将是一个十分有效的解决方案。 ### 回答2: Unity是一款非常强大的游戏引擎,在其中可以进行大量的开发工作。其中,Unity提供了很多的功能和工具,其中就包括了自定义菜单。 在Unity中,菜单是一种非常方便的工具,可以让用户轻松地查看所有的功能和对象,并且方便进行管理。如果用户想要自定义菜单,可以按照以下的步骤进行操作: 1. 创建一个新的编辑器窗口,负责显示自定义菜单。 2. 在这个编辑器窗口中,可以使用GUILayout或者IMGUI等工具来自定义绘制。 3. 使用EditorApplication.hierarchyWindowChanged事件去监听当场景objectId的集合发生了改变时触发。 4. 使用UnityEditor.GUILayout.Popup方法样式,用户可以为每个节点添加下拉箭头。 5. 使用自定义GUILayout.Button方法样式,用户可以为每个节点添加列表中的按钮。 上述步骤是在Unity中自定义菜单的基本过程,用户可以根据自己的需求进行更改和调整。自定义菜单可以大大提高工作效率,让开发者更加方便地管理和操作游戏中的场景、对象和功能。 ### 回答3: Unity是一款十分强大的游戏引擎,是许多游戏制作人员所钟爱的工具。Unity自带的菜单栏虽然已经很强大,但是我们还是有时候需要自定义菜单,来更好的实现游戏中的各种功能。这里我们将介绍如何使用Unity自定义菜单。 首先,打开Unity的编辑器并打开项目。然后在项目中新建一个C#脚本,并将其命名为“CustomMenu.cs”。我们将在这个脚本中编写我们的菜单。 接下来,我们需要为我们的菜单设置一个名称。在“CustomMenu.cs”中,使用“[MenuItem(“Custom/MyMenu”)]”,产生一个名为“MyMenu”的菜单。 接下来,我们可以在Unity的编辑器中创建一个新的文件夹,将其命名为“Custom”,这个文件夹将成为我们创建的菜单的父级。 接下来,在“CustomMenu.cs”中,我们可以使用“[MenuItem(“Custom/MyMenu/Do Something”)]”创建菜单的子项,并添加相应的函数来实现这个子项的功能。 最后,在Unity中运行我们的项目,并点击菜单栏“Custom”选项,我们就可以看到我们刚刚创建的菜单了。当我们点击“MyMenu”时,会显示“Do Something”子项。当我们点击“Do Something”时,它将调用相应的函数并执行相应的操作。 综上所述,Unity自定义菜单的实现方法是很简单的。我们只需要编写一个包含菜单名称和相应函数的脚本即可。可以根据需要创建任意多的子项,并为它们添加相应的功能。自定义菜单能够帮助我们更好地实现游戏中的各种功能,提高我们的工作效率,让我们更加专注于游戏的创作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值