2025-02-09 23:47:42 -05:00
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
2026-02-13 17:40:50 +08:00
|
|
|
|
using System.Linq;
|
2025-10-05 11:45:32 +08:00
|
|
|
|
using System.Threading.Tasks;
|
2025-06-14 20:47:45 +08:00
|
|
|
|
using DG.Tweening;
|
2026-05-02 22:10:19 +08:00
|
|
|
|
using Lean.Pool;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
using Ichni.RhythmGame;
|
2025-02-19 19:01:21 -05:00
|
|
|
|
using Michsky.MUIP;
|
2025-04-13 14:04:17 +08:00
|
|
|
|
using Sirenix.Utilities;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
using TMPro;
|
2025-08-10 16:00:46 +08:00
|
|
|
|
using Unity.VisualScripting;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
using UnityEngine;
|
2025-04-02 18:18:25 -04:00
|
|
|
|
using UnityEngine.InputSystem;
|
2025-02-19 19:01:21 -05:00
|
|
|
|
using UnityEngine.Serialization;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Ichni.Editor
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class HierarchyTab : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
public GameObject indentationLinePrefab;
|
2025-02-11 22:58:56 -05:00
|
|
|
|
|
2025-02-09 23:47:42 -05:00
|
|
|
|
public GameElement connectedGameElement;
|
|
|
|
|
|
public HierarchyTab parentTab;
|
|
|
|
|
|
public List<HierarchyTab> childTabList;
|
2025-02-11 22:58:56 -05:00
|
|
|
|
|
2025-02-09 23:47:42 -05:00
|
|
|
|
public int tabLayer;
|
|
|
|
|
|
public bool isSelected;
|
|
|
|
|
|
public bool isExpanded;
|
2025-02-20 15:25:42 +08:00
|
|
|
|
public Image BgImage;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
public RectTransform tabRect;
|
|
|
|
|
|
public LayoutElement layoutElement;
|
|
|
|
|
|
public RectTransform tabMainRect;
|
|
|
|
|
|
public Button tabButton;
|
|
|
|
|
|
public Button expandButton;
|
2025-02-19 19:01:21 -05:00
|
|
|
|
public DoubleCheckButton deleteButton;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
public TMP_Text tabButtonText;
|
|
|
|
|
|
|
2026-05-02 22:10:19 +08:00
|
|
|
|
private List<GameObject> indentationLines = new List<GameObject>();
|
|
|
|
|
|
|
|
|
|
|
|
public void SetTab(GameElement targetElement, GameElement parentElement, bool animate = true)
|
2025-02-09 23:47:42 -05:00
|
|
|
|
{
|
2026-05-02 22:10:19 +08:00
|
|
|
|
if (animate)
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.localScale = Vector3.one;
|
|
|
|
|
|
transform.DOScale(Vector3.one, 0.2f).SetEase(Ease.OutCirc).From(new Vector3(1, 0, 1));
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.DOKill();
|
|
|
|
|
|
transform.localScale = Vector3.one;
|
|
|
|
|
|
}
|
2025-02-11 22:58:56 -05:00
|
|
|
|
connectedGameElement = targetElement;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
tabButtonText.text = targetElement.elementName;
|
|
|
|
|
|
targetElement.connectedTab = this;
|
|
|
|
|
|
this.isExpanded = false;
|
|
|
|
|
|
this.isSelected = false;
|
|
|
|
|
|
this.childTabList = new List<HierarchyTab>();
|
|
|
|
|
|
|
2026-05-02 22:10:19 +08:00
|
|
|
|
// 清除旧的缩进线
|
|
|
|
|
|
for (int i = indentationLines.Count - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (indentationLines[i] != null)
|
|
|
|
|
|
Destroy(indentationLines[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
indentationLines.Clear();
|
|
|
|
|
|
|
2025-02-09 23:47:42 -05:00
|
|
|
|
if (parentElement == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.tabLayer = 0;
|
|
|
|
|
|
this.parentTab = null;
|
|
|
|
|
|
this.transform.SetAsLastSibling();
|
2025-02-11 22:58:56 -05:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-02-09 23:47:42 -05:00
|
|
|
|
this.parentTab = parentElement.connectedTab;
|
2025-02-12 01:57:18 +08:00
|
|
|
|
parentElement.connectedTab.childTabList.Add(this);
|
2025-02-09 23:47:42 -05:00
|
|
|
|
this.tabLayer = this.parentTab.tabLayer + 1;
|
2025-02-18 10:30:11 -05:00
|
|
|
|
this.transform.SetSiblingIndex(this.parentTab.transform.GetSiblingIndex() + GetAllChildrenCount(this.parentTab));
|
2025-02-21 15:30:14 +08:00
|
|
|
|
|
2025-02-09 23:47:42 -05:00
|
|
|
|
if (!this.parentTab.isExpanded)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.isExpanded = false;
|
2026-05-02 22:10:19 +08:00
|
|
|
|
var pt = this.parentTab;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
SetExpansion(false);
|
2026-05-02 22:10:19 +08:00
|
|
|
|
pt.SetStatus();
|
|
|
|
|
|
return;
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i <= this.tabLayer; i++)
|
|
|
|
|
|
{
|
2025-02-19 19:01:21 -05:00
|
|
|
|
float lineX = 30 * i - 15;
|
2025-03-16 01:45:49 +08:00
|
|
|
|
var d = Instantiate(indentationLinePrefab, tabRect);
|
|
|
|
|
|
d.GetComponent<RectTransform>().anchoredPosition = new Vector2(lineX, 0);
|
2026-05-02 22:10:19 +08:00
|
|
|
|
indentationLines.Add(d);
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
2026-05-02 22:10:19 +08:00
|
|
|
|
parentTab?.SetStatus();
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
2025-02-11 22:58:56 -05:00
|
|
|
|
|
2025-02-09 23:47:42 -05:00
|
|
|
|
|
2025-02-19 19:01:21 -05:00
|
|
|
|
float posX = (30 * tabLayer);
|
2025-02-09 23:47:42 -05:00
|
|
|
|
tabMainRect.anchoredPosition = new Vector2(posX, tabMainRect.anchoredPosition.y);
|
2026-05-02 22:10:19 +08:00
|
|
|
|
tabButton.onClick.RemoveAllListeners();
|
2025-02-11 22:58:56 -05:00
|
|
|
|
tabButton.onClick.AddListener(SelectGameElement);
|
2026-05-02 22:10:19 +08:00
|
|
|
|
expandButton.onClick.RemoveAllListeners();
|
2025-02-09 23:47:42 -05:00
|
|
|
|
expandButton.onClick.AddListener(ExpandOrFold);
|
2025-02-19 19:06:26 -05:00
|
|
|
|
deleteButton.onConfirm = () => EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElement(connectedGameElement);
|
2025-04-13 14:04:17 +08:00
|
|
|
|
|
|
|
|
|
|
SetStatus();
|
2025-10-05 11:45:32 +08:00
|
|
|
|
|
2025-04-13 14:04:17 +08:00
|
|
|
|
}
|
2025-10-05 11:45:32 +08:00
|
|
|
|
private void OnDestroy()
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.DOKill();
|
2026-05-02 22:10:19 +08:00
|
|
|
|
// 清除缩进线
|
|
|
|
|
|
for (int i = indentationLines.Count - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (indentationLines[i] != null)
|
|
|
|
|
|
Destroy(indentationLines[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
indentationLines.Clear();
|
2025-10-05 11:45:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-13 14:04:17 +08:00
|
|
|
|
public void SetStatus()
|
|
|
|
|
|
{
|
2025-06-30 16:37:34 +08:00
|
|
|
|
expandButton.gameObject.SetActive(!connectedGameElement.childElementList.IsNullOrEmpty());
|
2025-06-14 20:47:45 +08:00
|
|
|
|
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public partial class HierarchyTab
|
|
|
|
|
|
{
|
|
|
|
|
|
private int GetAllChildrenCount(HierarchyTab tab)
|
|
|
|
|
|
{
|
|
|
|
|
|
int c = tab.childTabList.Count;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < tab.childTabList.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
c += GetAllChildrenCount(tab.childTabList[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
|
|
}
|
2025-07-17 16:44:38 +08:00
|
|
|
|
public void ExecuteOrSelect()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (EditorManager.instance.uiManager.hierarchy.NeedExecute)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.uiManager.hierarchy.upLoadElement = connectedGameElement;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SelectGameElement();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-11 22:58:56 -05:00
|
|
|
|
|
2025-02-21 19:36:03 +08:00
|
|
|
|
public void SelectGameElement()
|
2025-02-11 22:58:56 -05:00
|
|
|
|
{
|
2025-04-02 18:18:25 -04:00
|
|
|
|
if (Keyboard.current.leftCtrlKey.isPressed)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!isSelected)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.operationManager.AddSelectElement(connectedGameElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.operationManager.RemoveSelectElement(connectedGameElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.operationManager.ClearSelectedElements();
|
|
|
|
|
|
EditorManager.instance.operationManager.AddSelectElement(connectedGameElement);
|
|
|
|
|
|
}
|
2025-08-10 16:00:46 +08:00
|
|
|
|
if (EditorManager.instance.useQuickMove)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (connectedGameElement is IHaveTransformSubmodule haveTransformSubmodule)
|
|
|
|
|
|
{
|
|
|
|
|
|
QuickMover quickMover = Instantiate(EditorManager.instance.basePrefabs.QuickMoveObj).GetComponent<QuickMover>();
|
|
|
|
|
|
quickMover.Initialize(haveTransformSubmodule);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (connectedGameElement is NoteBase noteBase && noteBase.noteVisual != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
QuickMover quickMover = Instantiate(EditorManager.instance.basePrefabs.QuickMoveObj).GetComponent<QuickMover>();
|
|
|
|
|
|
quickMover.Initialize(noteBase.noteVisual);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (QuickMover.instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Destroy(QuickMover.instance.gameObject);
|
|
|
|
|
|
QuickMover.instance = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-13 14:04:17 +08:00
|
|
|
|
|
2025-02-17 14:46:14 -05:00
|
|
|
|
EditorManager.instance.uiManager.inspector.SetInspector(connectedGameElement);
|
2025-07-19 13:52:42 +08:00
|
|
|
|
|
2025-02-11 22:58:56 -05:00
|
|
|
|
}
|
2026-02-13 17:40:50 +08:00
|
|
|
|
public void MoveTab(bool isUp)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. 基础合法性检查:根节点或孤立节点无法移动
|
|
|
|
|
|
if (parentTab == null || connectedGameElement.parentElement == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前层级的列表
|
|
|
|
|
|
var tabList = parentTab.childTabList;
|
|
|
|
|
|
int tabIndex = tabList.IndexOf(this);
|
|
|
|
|
|
var elementList = connectedGameElement.parentElement.childElementList;
|
|
|
|
|
|
int elemIndex = elementList.IndexOf(connectedGameElement);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算目标索引
|
|
|
|
|
|
int targetTabIndex = isUp ? tabIndex - 1 : tabIndex + 1;
|
|
|
|
|
|
int targetElemIndex = isUp ? elemIndex - 1 : elemIndex + 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 边界检查:如果是第一个往上或最后一个往下,则返回
|
|
|
|
|
|
if (targetTabIndex < 0 || targetTabIndex >= tabList.Count) return;
|
|
|
|
|
|
if (targetElemIndex < 0 || targetElemIndex >= elementList.Count) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取目标对象
|
|
|
|
|
|
var targetTab = tabList[targetTabIndex];
|
|
|
|
|
|
var targetElem = elementList[targetElemIndex];
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 交换逻辑数据顺序(List 内部排序)
|
|
|
|
|
|
tabList[tabIndex] = targetTab;
|
|
|
|
|
|
tabList[targetTabIndex] = this;
|
|
|
|
|
|
|
|
|
|
|
|
elementList[elemIndex] = targetElem;
|
|
|
|
|
|
elementList[targetElemIndex] = connectedGameElement;
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 处理 UI Tab 的 Sibling Index(解决偏移问题的核心)
|
|
|
|
|
|
List<Transform> thisSubTree = GetTabSubTreeTransforms(this);
|
|
|
|
|
|
List<Transform> targetSubTree = GetTabSubTreeTransforms(targetTab);
|
|
|
|
|
|
|
|
|
|
|
|
if (thisSubTree.Count > 0 && targetSubTree.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isUp)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 向上移:正序,插到目标分支的最上方
|
|
|
|
|
|
int insertIndex = targetSubTree[0].GetSiblingIndex();
|
|
|
|
|
|
for (int i = 0; i < thisSubTree.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
thisSubTree[i].SetSiblingIndex(insertIndex + i);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 向下移:逆序,依次插到目标分支最末尾的索引位置
|
|
|
|
|
|
// 这样先移过去的会被后移过去的顶到后面,保持原有父子相对顺序
|
|
|
|
|
|
int targetLastIndex = targetSubTree[targetSubTree.Count - 1].GetSiblingIndex();
|
|
|
|
|
|
for (int i = thisSubTree.Count - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
thisSubTree[i].SetSiblingIndex(targetLastIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 处理场景 GameElement 的 Sibling Index(同理)
|
|
|
|
|
|
List<Transform> thisElemSubTree = GetElementSubTreeTransforms(connectedGameElement);
|
|
|
|
|
|
List<Transform> targetElemSubTree = GetElementSubTreeTransforms(targetElem);
|
|
|
|
|
|
|
|
|
|
|
|
if (thisElemSubTree.Count > 0 && targetElemSubTree.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isUp)
|
|
|
|
|
|
{
|
|
|
|
|
|
int insertIndex = targetElemSubTree[0].GetSiblingIndex();
|
|
|
|
|
|
for (int i = 0; i < thisElemSubTree.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
thisElemSubTree[i].SetSiblingIndex(insertIndex + i);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
int targetLastIndex = targetElemSubTree[targetElemSubTree.Count - 1].GetSiblingIndex();
|
|
|
|
|
|
for (int i = thisElemSubTree.Count - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
thisElemSubTree[i].SetSiblingIndex(targetLastIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//奇妙的特判阶段
|
|
|
|
|
|
foreach (var i in parentTab.childTabList)
|
|
|
|
|
|
{
|
|
|
|
|
|
i.connectedGameElement.Refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
parentTab.connectedGameElement.Refresh();
|
|
|
|
|
|
|
|
|
|
|
|
if (parentTab.connectedGameElement is Track track)
|
|
|
|
|
|
{
|
|
|
|
|
|
track.trackPathSubmodule.pathNodeList =
|
|
|
|
|
|
track.childElementList.OfType<PathNode>().ToList();
|
|
|
|
|
|
track.trackPathSubmodule.SetPathPoints();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取tab及其所有子tab的transform(前序遍历)
|
|
|
|
|
|
private List<Transform> GetTabSubTreeTransforms(HierarchyTab tab)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<Transform> list = new List<Transform>();
|
|
|
|
|
|
list.Add(tab.transform);
|
|
|
|
|
|
foreach (var child in tab.childTabList)
|
|
|
|
|
|
list.AddRange(GetTabSubTreeTransforms(child));
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取GameElement及其所有子元素的transform(前序遍历)
|
|
|
|
|
|
private List<Transform> GetElementSubTreeTransforms(GameElement element)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<Transform> list = new List<Transform>();
|
|
|
|
|
|
if (element.transform != null)
|
|
|
|
|
|
list.Add(element.transform);
|
|
|
|
|
|
foreach (var child in element.childElementList)
|
|
|
|
|
|
list.AddRange(GetElementSubTreeTransforms(child));
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
2025-06-14 20:47:45 +08:00
|
|
|
|
public void ExpandOrFold()
|
2025-06-29 19:52:19 +08:00
|
|
|
|
{
|
|
|
|
|
|
ExpandOrFold(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
public void ExpandOrFold(bool forceAllExPand = false)
|
2025-02-09 23:47:42 -05:00
|
|
|
|
{
|
|
|
|
|
|
this.childTabList.RemoveAll(s => s == null);
|
2025-02-11 22:58:56 -05:00
|
|
|
|
isExpanded = !isExpanded;
|
2025-06-14 20:47:45 +08:00
|
|
|
|
ExpandAnim();
|
2025-02-11 22:58:56 -05:00
|
|
|
|
if (isExpanded)
|
|
|
|
|
|
{
|
2025-06-29 19:52:19 +08:00
|
|
|
|
connectedGameElement.ScanAndAddEnableTypes();
|
|
|
|
|
|
List<GameElement> FixedList = !forceAllExPand ? connectedGameElement.GetChildrenByTypes() : connectedGameElement.childElementList;
|
|
|
|
|
|
|
2025-10-05 11:45:32 +08:00
|
|
|
|
ExpandAsync(FixedList);
|
2025-04-13 14:04:17 +08:00
|
|
|
|
|
2025-02-11 22:58:56 -05:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-03-09 10:56:58 +08:00
|
|
|
|
//expandButton.transform.Rotate(new Vector3(0, 0, 180));
|
2025-02-11 22:58:56 -05:00
|
|
|
|
for (int i = childTabList.Count - 1; i >= 0; i--)
|
2025-02-12 01:57:18 +08:00
|
|
|
|
{
|
|
|
|
|
|
childTabList[i].SetExpansion(isExpanded);
|
|
|
|
|
|
}
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SetExpansion(bool expand)
|
|
|
|
|
|
{
|
2025-02-11 22:58:56 -05:00
|
|
|
|
if (!expand && isExpanded)
|
2025-02-09 23:47:42 -05:00
|
|
|
|
{
|
2026-05-02 22:10:19 +08:00
|
|
|
|
for (int i = childTabList.Count - 1; i >= 0; i--)
|
2025-02-09 23:47:42 -05:00
|
|
|
|
{
|
2026-05-02 22:10:19 +08:00
|
|
|
|
if (childTabList[i] != null)
|
|
|
|
|
|
childTabList[i].SetExpansion(expand);
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-12 01:57:18 +08:00
|
|
|
|
if (!expand)
|
2025-02-09 23:47:42 -05:00
|
|
|
|
{
|
2026-05-02 22:10:19 +08:00
|
|
|
|
CleanupAndDespawn();
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-02 22:10:19 +08:00
|
|
|
|
|
|
|
|
|
|
private void CleanupAndDespawn()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (connectedGameElement != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果该元素还在选中列表中,先移除(须在 connectedTab=null 之前执行)
|
|
|
|
|
|
if (isSelected)
|
|
|
|
|
|
{
|
|
|
|
|
|
var sel = EditorManager.instance.operationManager.currentSelectedElements;
|
|
|
|
|
|
sel.Remove(connectedGameElement);
|
|
|
|
|
|
isSelected = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
connectedGameElement.connectedTab = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
parentTab?.childTabList.Remove(this);
|
|
|
|
|
|
EditorManager.instance.uiManager.hierarchy.tabList.Remove(this);
|
|
|
|
|
|
|
|
|
|
|
|
transform.DOKill();
|
|
|
|
|
|
|
|
|
|
|
|
tabButton.onClick.RemoveAllListeners();
|
|
|
|
|
|
expandButton.onClick.RemoveAllListeners();
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = indentationLines.Count - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (indentationLines[i] != null)
|
|
|
|
|
|
Destroy(indentationLines[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
indentationLines.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
connectedGameElement = null;
|
|
|
|
|
|
parentTab = null;
|
|
|
|
|
|
childTabList?.Clear();
|
|
|
|
|
|
isExpanded = false;
|
|
|
|
|
|
isExpandDone = true;
|
|
|
|
|
|
tabLayer = 0;
|
|
|
|
|
|
|
|
|
|
|
|
LeanPool.Despawn(gameObject);
|
|
|
|
|
|
}
|
2025-06-14 20:47:45 +08:00
|
|
|
|
private void ExpandAnim()
|
|
|
|
|
|
{
|
|
|
|
|
|
expandButton.transform.DORotate(new Vector3(0, 0, !isExpanded ? 0f : 180f), 0.2f);
|
|
|
|
|
|
}
|
2025-10-05 11:45:32 +08:00
|
|
|
|
|
|
|
|
|
|
public bool isExpandDone = true;
|
|
|
|
|
|
private void ExpandImmediately(List<GameElement> FixedList)
|
2025-03-09 10:56:58 +08:00
|
|
|
|
{
|
2025-06-29 21:28:49 +08:00
|
|
|
|
float StrandTimeWhileStartUp = EditorManager.instance.CurrentFrameRate;
|
2025-10-05 11:45:32 +08:00
|
|
|
|
float frameTime = 1f / StrandTimeWhileStartUp * 3f;
|
|
|
|
|
|
|
2025-06-29 19:52:19 +08:00
|
|
|
|
for (var index = 0; index < FixedList.Count; index++)
|
2025-03-09 10:56:58 +08:00
|
|
|
|
{
|
2025-06-29 19:52:19 +08:00
|
|
|
|
var childElement = FixedList[index];
|
2025-06-14 20:47:45 +08:00
|
|
|
|
EditorManager.instance.uiManager.hierarchy.GenerateTab(childElement, connectedGameElement);
|
2026-05-02 22:10:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public IEnumerator ExpandSyncBatched()
|
|
|
|
|
|
{
|
|
|
|
|
|
connectedGameElement.ScanAndAddEnableTypes();
|
|
|
|
|
|
isExpanded = true;
|
|
|
|
|
|
isExpandDone = false;
|
|
|
|
|
|
ExpandAnim();
|
2025-10-05 11:45:32 +08:00
|
|
|
|
|
2026-05-02 22:10:19 +08:00
|
|
|
|
var children = connectedGameElement.childElementList;
|
|
|
|
|
|
int batchCount = 0;
|
|
|
|
|
|
for (int i = 0; i < children.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!isExpanded) break;
|
|
|
|
|
|
if (children[i].connectedTab == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.uiManager.hierarchy.GenerateTab(children[i], connectedGameElement, false);
|
|
|
|
|
|
batchCount++;
|
|
|
|
|
|
if (batchCount >= 15)
|
|
|
|
|
|
{
|
|
|
|
|
|
batchCount = 0;
|
|
|
|
|
|
yield return null;
|
|
|
|
|
|
if (!isExpanded) break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-09 10:56:58 +08:00
|
|
|
|
}
|
2026-05-02 22:10:19 +08:00
|
|
|
|
|
|
|
|
|
|
isExpandDone = true;
|
2025-03-09 10:56:58 +08:00
|
|
|
|
}
|
2026-05-02 22:10:19 +08:00
|
|
|
|
|
2025-10-05 11:45:32 +08:00
|
|
|
|
async void ExpandAsync(List<GameElement> FixedList)
|
|
|
|
|
|
{
|
|
|
|
|
|
isExpandDone = false;
|
|
|
|
|
|
for (var index = 0; index < FixedList.Count; index++)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
var childElement = FixedList[index];
|
|
|
|
|
|
await EditorManager.instance.uiManager.hierarchy.GenerateTabAsync(childElement, connectedGameElement);
|
|
|
|
|
|
if (!isExpanded) break;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
isExpandDone = true;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-02-09 23:47:42 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|