using UnityEngine; using UnityEngine.UI; using XMLTool; using System.Collections.Generic; using TMPro; using UnityEditor.Hardware; using DG.Tweening; namespace QFramework.Example { public class UIBody3DMenuTreeData : UIPanelData { public Body3D.Body body; } public partial class UIBody3DMenuTree : UIPanel { class ObjBtnData { public Button btn; public Body3D.Body body; public ObjToggleStatus status; public Dictionary objBtnDataMap = new Dictionary(); public ObjBtnData(Dictionary objBtnDataMap, Button btn, Body3D.Body body) { this.objBtnDataMap = objBtnDataMap; this.btn = btn; this.body = body; btn.onClick.AddListener(() => { switch (status) { case ObjToggleStatus.None: case ObjToggleStatus.Half: SetStatus(ObjToggleStatus.Full); break; case ObjToggleStatus.Full: SetStatus(ObjToggleStatus.None); break; } }); } public void SetStatus(ObjToggleStatus status) { this.status = status; RefreshStatus(); } public void RefreshStatus() { switch (status) { case ObjToggleStatus.None: CheckActive(); foreach (var sub in body.subBody) { if (objBtnDataMap.ContainsKey(sub.Value)) { objBtnDataMap[sub.Value].SetStatus(status); } } SetUpStatus(body, true); break; case ObjToggleStatus.Half: CheckActive(); SetUpStatus(body, false); break; case ObjToggleStatus.Full: CheckActive(); foreach (var sub in body.subBody) { if (objBtnDataMap.ContainsKey(sub.Value)) { objBtnDataMap[sub.Value].SetStatus(status); } } SetUpStatus(body, true); break; } RefreshUI(); } public void CheckActive() { switch (status) { case ObjToggleStatus.None: Utility.FindObj(body.Path).SetActive(false); break; case ObjToggleStatus.Half: case ObjToggleStatus.Full: Utility.FindObj(body.Path).SetActive(true); break; } } public void RefreshParent(ObjToggleStatus status) { this.status = status; CheckActive(); RefreshUI(); } public void SetUpStatus(Body3D.Body body, bool needCheck) { var parent = body.parent; if (parent != null && objBtnDataMap.ContainsKey(parent)) { if (needCheck) { bool allOn = true; bool allNone = true; // 遍历 body 的子元素 subBody foreach (var sub in parent.subBody) { // 检查 objBtnDataMap 中是否包含当前子元素的值 if (objBtnDataMap.ContainsKey(sub.Value)) { // 获取当前子元素对应的按钮数据的状态 var status = objBtnDataMap[sub.Value].status; // 如果当前子元素的状态不是 Full,说明不是所有子元素都是 Full 状态 if (status != ObjToggleStatus.Full) { allOn = false; } // 如果当前子元素的状态不是 None,说明不是所有子元素都是 None 状态 if (status != ObjToggleStatus.None) { allNone = false; } } else { // 如果 objBtnDataMap 中不包含当前子元素的值,说明不是所有状态都符合要求 allOn = false; allNone = false; break; } } // 如果所有子元素的状态都是 Full if (allOn) { // 将当前 body 的状态设置为 Full objBtnDataMap[parent].RefreshParent(ObjToggleStatus.Full); } // 如果所有子元素的状态都是 None else if (allNone) { // 将当前 body 的状态设置为 None objBtnDataMap[parent].RefreshParent(ObjToggleStatus.None); } else { objBtnDataMap[parent].RefreshParent(ObjToggleStatus.Half); } SetUpStatus(parent, true); } else { if (objBtnDataMap.ContainsKey(parent)) { objBtnDataMap[parent].SetStatus(ObjToggleStatus.Half); SetUpStatus(parent, false); } } } } public void RefreshUI() { switch (status) { case ObjToggleStatus.None: btn.transform.Find("Full").gameObject.SetActive(false); btn.transform.Find("Half").gameObject.SetActive(false); break; case ObjToggleStatus.Half: btn.transform.Find("Full").gameObject.SetActive(false); btn.transform.Find("Half").gameObject.SetActive(true); break; case ObjToggleStatus.Full: btn.transform.Find("Full").gameObject.SetActive(true); btn.transform.Find("Half").gameObject.SetActive(false); break; } } } Dictionary searchItemMap = new Dictionary(); Dictionary objBtnDataMap = new Dictionary(); enum ObjToggleStatus { None, Half, Full } DOTweenAnimation contentAnim; protected override void OnInit(IUIData uiData = null) { contentAnim = RootContent.GetComponent(); // please add init code here Close.onClick.AddListener(() => { Hide(); StringEventSystem.Global.Send("UIBody3DMenuTreeClose"); }); Input.onSelect.AddListener(str => { SearchContent.gameObject.SetActive(true); Content.gameObject.SetActive(false); }); Input.onEndEdit.AddListener(str => { if (string.IsNullOrEmpty(str)) { SearchContent.gameObject.SetActive(false); Content.gameObject.SetActive(true); SearchContent.RemoveAllChildren(); } else { SearchContent.gameObject.SetActive(true); Content.gameObject.SetActive(false); RefreshSearchContent(str); } }); } protected override void OnOpen(IUIData uiData = null) { mData = uiData as UIBody3DMenuTreeData ?? new UIBody3DMenuTreeData(); contentAnim.DORestart(); Content.RemoveAllChildren(); objBtnDataMap.Clear(); 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; GameObject toggleObj = GameObject.Instantiate(Item.gameObject, targetParent); toggleObj.name = body.Name; Toggle uiToggle = toggleObj.transform.Find("ToggleContent/UI").GetComponent(); Button objBtn = toggleObj.transform.Find("ToggleContent/Obj").GetComponent