using UnityEngine; using UnityEngine.UI; using XMLTool; using System.Collections.Generic; namespace QFramework.Example { public class UIBody3DMenuTreeData : UIPanelData { public Body3D.Body body; } public partial class UIBody3DMenuTree : UIPanel { // 用于存储 Body3D.Body 和对应的 Toggle 的映射关系 protected override void OnInit(IUIData uiData = null) { // please add init code here Close.onClick.AddListener(() => { Hide(); UIKit.OpenPanelAsync().ToAction().StartGlobal(); }); } protected override void OnOpen(IUIData uiData = null) { mData = uiData as UIBody3DMenuTreeData ?? new UIBody3DMenuTreeData(); Content.RemoveAllChildren(); BuildTreeUI(mData.body); } private void BuildTreeUI(Body3D.Body data, int depth = 0, Transform parent = null) { foreach (var bodyPair in data.subBody) { Body3D.Body body = bodyPair.Value; // 确定父容器 Transform targetParent = parent != null ? parent : Content; // 创建Toggle GameObject toggleObj = GameObject.Instantiate(Item.gameObject, targetParent); toggleObj.name = body.Name; Toggle uiToggle = toggleObj.transform.Find("ToggleContent/UI").GetComponent(); Toggle objToggle = toggleObj.transform.Find("ToggleContent/Obj").GetComponent(); Text label = toggleObj.transform.Find("ToggleContent/Label").GetComponentInChildren(); label.text = body.Name; // 根据深度添加缩进 toggleObj.transform.Find("ToggleContent").GetComponent().padding = new RectOffset(depth * 15, 5, 2, 2); if (depth != 0) { toggleObj.SetActive(false); } // 递归构建子节点 Transform subContent = toggleObj.transform.Find("SubContent"); // 设置Toggle的监听事件 uiToggle.onValueChanged.AddListener((isOn) => { for (int i = 0; i < subContent.childCount; i++) { subContent.GetChild(i).gameObject.SetActive(isOn); } }); // 为objToggle添加点击事件处理逻辑 objToggle.onValueChanged.AddListener((isOn) => { SetObjectVisibility(body, isOn, subContent); }); if (body.subBody.Count > 0) { uiToggle.gameObject.SetActive(true); BuildTreeUI(body, depth + 1, subContent); //HideSubBody(body); // 初始时隐藏子节点 } else { uiToggle.gameObject.SetActive(false); Debug.Log($"节点 {body.Name} 没有子节点。"); } } } // 根据body和subbody中的path设置物体的显隐,同时设置子UI中的objToggle状态 private void SetObjectVisibility(Body3D.Body body, bool isOn, Transform subContent) { // 处理当前body的path对应的物体 GameObject targetObj = Utility.FindObj(body.Path); if (targetObj != null) { targetObj.SetActive(isOn); } // 递归处理subbody中的path对应的物体,并设置子UI中的objToggle状态 int index = 0; foreach (var subBodyPair in body.subBody) { Body3D.Body subBody = subBodyPair.Value; if (subContent.childCount > index) { Transform childToggleObj = subContent.GetChild(index); Toggle childObjToggle = childToggleObj.transform.Find("ToggleContent/Obj").GetComponent(); childObjToggle.isOn = isOn; // 设置子UI中的objToggle状态 Transform childSubContent = childToggleObj.transform.Find("SubContent"); SetObjectVisibility(subBody, isOn, childSubContent); } index++; } } protected override void OnShow() { } protected override void OnHide() { } protected override void OnClose() { } } }