Skip to content

Instantly share code, notes, and snippets.

@liveasnotes
Last active September 6, 2021 11:18
Show Gist options
  • Select an option

  • Save liveasnotes/bfedbf2c8c225905a62e65b471118e1e to your computer and use it in GitHub Desktop.

Select an option

Save liveasnotes/bfedbf2c8c225905a62e65b471118e1e to your computer and use it in GitHub Desktop.
UnityHierarchyAlphabeticalSort_vleCFZj
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace liveasnotes.EditorExtension
{
[InitializeOnLoad]
public class HierarchyObjectsAlphabeticalSorter
{
// cf. https://sleepygamersmemo.blogspot.com/2018/08/unity-sort-hierarchy.html
static bool isAlphabeticalSortingEnabled = true; // set with option in preferences
static bool isProcessEnabled = false;
static bool isProcessOngoing = false;
static bool debugSorter = true;
static bool hasSiblingIndexChanged;
static HierarchyObjectsAlphabeticalSorter()
{
EditorApplication.hierarchyChanged += OnHierarchyChanged;
}
static void OnHierarchyChanged()
{
if (debugSorter)
{
Debug.Log("Modification Observed!");
Debug.Log("@Modified: " + isProcessEnabled + ", " + isProcessOngoing);
}
if (hasSiblingIndexChanged)
{
hasSiblingIndexChanged = false;
isProcessEnabled = false;
}
else
{
isProcessEnabled = true;
}
SortHierarchyObjects();
}
static void SortHierarchyObjects()
{
if (isProcessEnabled && !isProcessOngoing)
{
if (debugSorter)
{
Debug.Log("@Process START: " + isProcessEnabled + ", " + isProcessOngoing);
}
isProcessOngoing = true;
Transform[] allTransforms = UnityEngine.Object.FindObjectsOfType<Transform>();
foreach (IGrouping<Transform, Transform> siblings in allTransforms.GroupBy(_obj => _obj.parent))
{
if (siblings.Key && siblings.Key.TryGetComponent(out Canvas canvas))
{
// `siblings.Key` -> Avoid Null Reference Exception caused by that the root object has null parent.
// `*.TryGetComponent(out Canvas *)` -> Check whether it has canvas to avoid reordering its item.
}
else
{
int i = -1;
foreach (Transform t in siblings.OrderBy(_obj => _obj.name))
{
i += 1;
t.SetSiblingIndex(i);
}
}
}
hasSiblingIndexChanged = true;
// - The all above modifications with SetSiblingIndex() are stacked on `hierarchyChanged`
// and the event seems to be called just once after exiting `EditorApplication.update`.
// - This flag is set for a workaround to skip the process
// that causes an endless loop of modification.
isProcessOngoing = false;
if (debugSorter)
{
Debug.Log("@Process END: " + isProcessEnabled + ", " + isProcessOngoing);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment