181 lines
5.8 KiB
C#
181 lines
5.8 KiB
C#
|
|
#if UNITY_EDITOR
|
||
|
|
using UnityEngine;
|
||
|
|
using UnityEditor;
|
||
|
|
using System.Linq;
|
||
|
|
|
||
|
|
namespace Test_2022.Utils
|
||
|
|
{
|
||
|
|
public class HierarchySorter : EditorWindow
|
||
|
|
{
|
||
|
|
private static bool includeInactive = true;
|
||
|
|
private static bool sortRecursively = false;
|
||
|
|
|
||
|
|
[MenuItem("Tools/Hierarchy/Sort Immediate Children Only (A-Z)")]
|
||
|
|
private static void SortSelectedChildren()
|
||
|
|
{
|
||
|
|
GameObject[] selectedObjects = Selection.gameObjects;
|
||
|
|
|
||
|
|
if (selectedObjects.Length == 0)
|
||
|
|
{
|
||
|
|
EditorUtility.DisplayDialog("提示", "请先选择一个父对象!", "确定");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (GameObject parent in selectedObjects)
|
||
|
|
{
|
||
|
|
SortChildren(parent.transform);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[MenuItem("Tools/Hierarchy/Sort All Descendants (Recursive)")]
|
||
|
|
private static void SortSelectedChildrenRecursive()
|
||
|
|
{
|
||
|
|
GameObject[] selectedObjects = Selection.gameObjects;
|
||
|
|
|
||
|
|
if (selectedObjects.Length == 0)
|
||
|
|
{
|
||
|
|
EditorUtility.DisplayDialog("提示", "请先选择一个父对象!", "确定");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (GameObject parent in selectedObjects)
|
||
|
|
{
|
||
|
|
SortChildrenRecursive(parent.transform);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[MenuItem("Tools/Hierarchy/Open Sort Window...")]
|
||
|
|
private static void ShowWindow()
|
||
|
|
{
|
||
|
|
var window = GetWindow<HierarchySorter>("Hierarchy排序工具");
|
||
|
|
window.Show();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnGUI()
|
||
|
|
{
|
||
|
|
GUILayout.Label("Hierarchy 排序工具", EditorStyles.boldLabel);
|
||
|
|
GUILayout.Space(10);
|
||
|
|
|
||
|
|
includeInactive = EditorGUILayout.ToggleLeft(" 包含非激活对象 (Include Inactive)", includeInactive);
|
||
|
|
sortRecursively = EditorGUILayout.ToggleLeft(" 递归排序所有子层级 (Recursive)", sortRecursively);
|
||
|
|
|
||
|
|
GUILayout.Space(15);
|
||
|
|
|
||
|
|
string buttonText = sortRecursively ? "排序选中对象及其所有后代" : "仅排序选中对象的直接子级";
|
||
|
|
|
||
|
|
if (GUILayout.Button(buttonText, GUILayout.Height(40)))
|
||
|
|
{
|
||
|
|
SortSelectedWithOptions();
|
||
|
|
}
|
||
|
|
|
||
|
|
GUILayout.Space(10);
|
||
|
|
|
||
|
|
EditorGUILayout.HelpBox(
|
||
|
|
sortRecursively
|
||
|
|
? "模式:递归\n将排序选中对象下的所有层级物体。\n结构会被彻底重新整理。"
|
||
|
|
: "模式:仅直接子级\n只会排序第一层子对象。\n子对象的子对象保持原样(符合您的需求)。",
|
||
|
|
MessageType.Info
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void SortSelectedWithOptions()
|
||
|
|
{
|
||
|
|
GameObject[] selectedObjects = Selection.gameObjects;
|
||
|
|
|
||
|
|
if (selectedObjects.Length == 0)
|
||
|
|
{
|
||
|
|
EditorUtility.DisplayDialog("提示", "请先选择一个父对象!", "确定");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Undo.RecordObjects(selectedObjects, "Sort Children");
|
||
|
|
|
||
|
|
int totalSorted = 0;
|
||
|
|
foreach (GameObject parent in selectedObjects)
|
||
|
|
{
|
||
|
|
if (sortRecursively)
|
||
|
|
{
|
||
|
|
totalSorted += SortChildrenRecursive(parent.transform);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
totalSorted += SortChildren(parent.transform);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static int SortChildren(Transform parent)
|
||
|
|
{
|
||
|
|
if (parent == null) return 0;
|
||
|
|
|
||
|
|
var children = new System.Collections.Generic.List<Transform>();
|
||
|
|
|
||
|
|
for (int i = 0; i < parent.childCount; i++)
|
||
|
|
{
|
||
|
|
children.Add(parent.GetChild(i));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!includeInactive)
|
||
|
|
{
|
||
|
|
children = children.Where(c => c.gameObject.activeSelf).ToList();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (children.Count <= 1) return 0;
|
||
|
|
|
||
|
|
var sortedChildren = children.OrderBy(c => c.name).ToList();
|
||
|
|
|
||
|
|
bool orderChanged = false;
|
||
|
|
for (int i = 0; i < children.Count; i++)
|
||
|
|
{
|
||
|
|
if (children[i] != sortedChildren[i])
|
||
|
|
{
|
||
|
|
orderChanged = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (orderChanged)
|
||
|
|
{
|
||
|
|
for (int i = 0; i < sortedChildren.Count; i++)
|
||
|
|
{
|
||
|
|
Undo.SetTransformParent(sortedChildren[i], parent, "Sort Children");
|
||
|
|
sortedChildren[i].SetSiblingIndex(i);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static int SortChildrenRecursive(Transform parent)
|
||
|
|
{
|
||
|
|
if (parent == null) return 0;
|
||
|
|
|
||
|
|
int totalSorted = SortChildren(parent);
|
||
|
|
|
||
|
|
for (int i = 0; i < parent.childCount; i++)
|
||
|
|
{
|
||
|
|
Transform child = parent.GetChild(i);
|
||
|
|
if (child.childCount > 0)
|
||
|
|
{
|
||
|
|
totalSorted += SortChildrenRecursive(child);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return totalSorted;
|
||
|
|
}
|
||
|
|
|
||
|
|
[MenuItem("GameObject/Sort Children Alphabetically", false, 0)]
|
||
|
|
private static void ContextMenuSort()
|
||
|
|
{
|
||
|
|
SortSelectedChildren();
|
||
|
|
}
|
||
|
|
|
||
|
|
[MenuItem("GameObject/Sort Children Alphabetically (Recursive)", false, 1)]
|
||
|
|
private static void ContextMenuSortRecursive()
|
||
|
|
{
|
||
|
|
SortSelectedChildrenRecursive();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|