Files
ichni_Creator_Studio/Assets/Scripts/DynamicUI/Hierarchy/Hierarchy.cs

204 lines
8.2 KiB
C#
Raw Normal View History

2025-03-08 23:11:55 -05:00
using System;
2025-02-09 23:47:42 -05:00
using System.Collections;
using System.Collections.Generic;
2025-06-30 16:37:34 +08:00
using DG.Tweening;
2025-02-09 23:47:42 -05:00
using Ichni.RhythmGame;
using Unity.VisualScripting;
2025-02-09 23:47:42 -05:00
using UnityEngine;
using UnityEngine.UI;
2025-02-09 23:47:42 -05:00
namespace Ichni.Editor
{
public class Hierarchy : StaticWindow
{
public GameObject hierarchyTabPrefab;
public RectTransform tabContainer;
2025-03-08 23:11:55 -05:00
public Button addFolderButton;
2025-02-09 23:47:42 -05:00
public List<HierarchyTab> tabList;
2025-06-30 16:37:34 +08:00
public Button expandButtom;
public bool NeedExecute = false;
2025-03-08 23:11:55 -05:00
private void Awake()
{
tabList = new List<HierarchyTab>();
addFolderButton.onClick.AddListener(() =>
{
ElementFolder.GenerateElement("New Folder", Guid.NewGuid(), new List<string>(), true, null);
});
2025-06-30 16:37:34 +08:00
expandButtom.onClick.AddListener(Expand);
rectTransform = this.GetComponent<RectTransform>();
2025-03-08 23:11:55 -05:00
}
2025-02-11 22:58:56 -05:00
public HierarchyTab GenerateTab(GameElement targetElement, GameElement parentElement)
2025-02-09 23:47:42 -05:00
{
2025-02-11 22:58:56 -05:00
HierarchyTab tab = Instantiate(hierarchyTabPrefab, tabContainer).GetComponent<HierarchyTab>();
2025-02-09 23:47:42 -05:00
tab.SetTab(targetElement, parentElement);
tabList.Add(tab);
return tab;
2025-02-09 23:47:42 -05:00
}
2025-06-30 16:37:34 +08:00
public bool isExpand = false;
private RectTransform rectTransform;
public void Expand()
{
float originX = 225f;
isExpand = !isExpand;
// 用DOTween动画赋值
if (isExpand)
{
rectTransform.DOSizeDelta(
new Vector2(rectTransform.sizeDelta.x * 2, rectTransform.sizeDelta.y), 0.5f);
rectTransform.DOAnchorPos(
new Vector2(originX * 2, rectTransform.anchoredPosition.y), 0.5f);
enableButtonGroup.disableButton.GetComponent<RectTransform>().DOAnchorPos(
new Vector2(
enableButtonGroup.disableButton.GetComponent<RectTransform>().anchoredPosition.x * 3,
enableButtonGroup.disableButton.GetComponent<RectTransform>().anchoredPosition.y
), 0.5f);
expandButtom.GetComponent<RectTransform>().DOAnchorPos(
new Vector2(
expandButtom.GetComponent<RectTransform>().anchoredPosition.x * 2,
expandButtom.GetComponent<RectTransform>().anchoredPosition.y
), 0.5f);
}
else
{
rectTransform.DOSizeDelta(
new Vector2(rectTransform.sizeDelta.x / 2, rectTransform.sizeDelta.y), 0.5f);
rectTransform.DOAnchorPos(
new Vector2(originX, rectTransform.anchoredPosition.y), 0.5f);
enableButtonGroup.disableButton.GetComponent<RectTransform>().DOAnchorPos(
new Vector2(
enableButtonGroup.disableButton.GetComponent<RectTransform>().anchoredPosition.x / 3,
enableButtonGroup.disableButton.GetComponent<RectTransform>().anchoredPosition.y
), 0.5f);
expandButtom.GetComponent<RectTransform>().DOAnchorPos(
new Vector2(
expandButtom.GetComponent<RectTransform>().anchoredPosition.x / 2,
expandButtom.GetComponent<RectTransform>().anchoredPosition.y
), 0.5f);
}
}
2025-03-16 00:42:27 +08:00
2025-05-11 14:12:47 +08:00
public ScrollRect scrollRect;
public Vector2 vector2;
2025-06-29 21:28:49 +08:00
public void FindTab(GameElement targetElement)
{
if (targetElement.connectedTab != null)
{
// 如果已经有Tab了直接选中
targetElement.connectedTab.SelectGameElement();
getTabPos(targetElement.connectedTab);
return;
}
2025-06-29 21:28:49 +08:00
targetElement.ScanAndAddEnableTypes();
if (!EditorManager.instance.ExpandWhileClick)
{
var tab = EditorManager.instance.uiManager.hierarchy.GenerateTab(targetElement, null);
tab.SelectGameElement();
Destroy(tab.gameObject);
EditorManager.instance.uiManager.hierarchy.tabList.Remove(tab);
}
else
{
StartCoroutine(TryGetTab(targetElement));
}
2025-06-14 20:47:45 +08:00
}
public IEnumerator TryGetTab(GameElement targetElement)
{
// 1. 向上找到最近的有Tab的祖先
Stack<GameElement> stack = new Stack<GameElement>();
GameElement current = targetElement;
while (current != null && current.connectedTab == null)
{
2025-06-14 20:47:45 +08:00
stack.Push(current);
current = current.parentElement;
}
2025-06-14 20:47:45 +08:00
// 2. 如果有Tab的祖先存在依次展开回目标
HierarchyTab parentTab = current != null ? current.connectedTab : null;
while (stack.Count > 0)
{
2025-06-14 20:47:45 +08:00
var elem = stack.Pop();
// 只展开父Tab不直接生成Tab
if (elem.parentElement != null && elem.parentElement.connectedTab != null)
2025-05-24 14:34:12 +08:00
{
if (!elem.parentElement.connectedTab.isExpanded)
{
elem.parentElement.connectedTab.ExpandOrFold(true);
}
2025-06-29 21:28:49 +08:00
else if (elem.parentElement.connectedTab.ienumerator is null)
{
elem.parentElement.connectedTab.ExpandOrFold();
elem.parentElement.connectedTab.ExpandOrFold(true);//合上再展开,这思路也是没谁了
}
2025-06-29 21:28:49 +08:00
else
{
//他就在展开了,等下就好了
}
2025-06-14 20:47:45 +08:00
yield return null;
2025-05-24 14:34:12 +08:00
}
2025-06-14 20:47:45 +08:00
// 等待当前elem的Tab生成
while (elem.connectedTab == null)
2025-05-24 14:34:12 +08:00
{
2025-06-14 20:47:45 +08:00
yield return null;
2025-05-24 14:34:12 +08:00
}
2025-06-14 20:47:45 +08:00
parentTab = elem.connectedTab;
}
2025-05-24 14:34:12 +08:00
2025-06-14 20:47:45 +08:00
// 3. 等待目标Tab实例化
while (targetElement.connectedTab is null)
2025-06-14 20:47:45 +08:00
{
2025-06-14 20:47:45 +08:00
yield return null;
}
yield return null; // 等待一帧确保UI更新
getTabPos(targetElement.connectedTab);
}
void getTabPos(HierarchyTab finalTab)
{
// 修正定位算法
RectTransform tabRect = finalTab.GetComponent<RectTransform>();
RectTransform containerRect = tabContainer;
RectTransform viewportRect = scrollRect.viewport != null ? scrollRect.viewport : scrollRect.GetComponent<RectTransform>();
// Tab相对于内容顶部的距离正值为下负值为上
float tabTop = -tabRect.anchoredPosition.y;
float tabHeight = tabRect.rect.height;
float contentHeight = containerRect.rect.height;
float viewportHeight = viewportRect.rect.height;
// 目标让Tab居中或尽量居中
float targetCenter = tabTop + tabHeight / 2f;
float viewportCenter = viewportHeight / 2f;
float scrollOffset = targetCenter - viewportCenter;
// normalizedPosition = 1 - (scrollOffset / (contentHeight - viewportHeight))
float denominator = Mathf.Max(1f, contentHeight - viewportHeight);
float normalized = 1f - Mathf.Clamp01(scrollOffset / denominator);
scrollRect.verticalNormalizedPosition = normalized;
2025-06-14 20:47:45 +08:00
finalTab.SelectGameElement();
2025-06-29 21:28:49 +08:00
}
public GameElement upLoadElement = null;
public IEnumerator TryGetElement()
{
NeedExecute = true;
// 等待直到upLoadElement被赋值
if (upLoadElement == null)
{
yield return new WaitUntil(() => upLoadElement != null);
}
NeedExecute = false;
upLoadElement = null;
}
2025-02-09 23:47:42 -05:00
}
}