Created
July 10, 2024 08:16
-
-
Save WhiteOlivierus/d94b7d88b27250f171865cee06a1bac6 to your computer and use it in GitHub Desktop.
A way for monitoring changes in the unity editor hierarchy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using UnityEditor; | |
| using UnityEngine; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using Object = UnityEngine.Object; | |
| [InitializeOnLoad] | |
| public static class HierarchyMonitor | |
| { | |
| private static readonly Dictionary<GameObject, string> _previousNames = new(); | |
| private static readonly Dictionary<GameObject, Transform> _previousParents = new(); | |
| public delegate void GameObjectEventHandler(GameObject gameObject); | |
| public delegate void GameObjectRenamedEventHandler(GameObject editedObject); | |
| public delegate void GameObjectParentChangedEventHandler(GameObject gameObject, Transform oldParent, Transform newParent); | |
| public static event GameObjectEventHandler GameObjectAdded; | |
| public static event GameObjectEventHandler GameObjectRemoved; | |
| public static event GameObjectRenamedEventHandler GameObjectRenamed; | |
| public static event GameObjectParentChangedEventHandler GameObjectParentChanged; | |
| static HierarchyMonitor() | |
| { | |
| EditorApplication.hierarchyChanged += OnHierarchyChanged; | |
| RefreshPreviousState(); | |
| } | |
| private static void RefreshPreviousState() | |
| { | |
| _previousNames.Clear(); | |
| _previousParents.Clear(); | |
| GameObject[] gameObjects = Object.FindObjectsOfType<GameObject>(); | |
| foreach (GameObject gameObject in gameObjects) | |
| { | |
| if (gameObject.hideFlags != HideFlags.None || | |
| _previousNames.ContainsKey(gameObject)) | |
| { | |
| continue; | |
| } | |
| _previousNames.Add(gameObject, gameObject.name); | |
| _previousParents.Add(gameObject, gameObject.transform.parent); | |
| } | |
| } | |
| private static void OnHierarchyChanged() | |
| { | |
| GameObject[] currentGameObjects = Object.FindObjectsOfType<GameObject>(); | |
| foreach (GameObject gameObject in currentGameObjects) | |
| { | |
| HandleGameObjectAdded(gameObject); | |
| HandleGameObjectRenamed(gameObject); | |
| HandleGameObjectParentChanged(gameObject); | |
| } | |
| ICollection<GameObject> keys = _previousNames.Keys.ToList(); | |
| foreach (GameObject previousGameObject in keys) | |
| { | |
| HandleGameObjectDeleted(currentGameObjects, previousGameObject); | |
| } | |
| RefreshPreviousState(); | |
| } | |
| private static void HandleGameObjectDeleted(GameObject[] currentGameObjects, GameObject previousGameObject) | |
| { | |
| if (Array.Exists(currentGameObjects, obj => obj == previousGameObject)) | |
| { | |
| return; | |
| } | |
| Debug.Log($"GameObject removed: {_previousNames[previousGameObject]}"); | |
| GameObjectRemoved?.Invoke(previousGameObject); | |
| _previousNames.Remove(previousGameObject); | |
| } | |
| private static void HandleGameObjectRenamed(GameObject gameObject) | |
| { | |
| if (!_previousNames.ContainsKey(gameObject) || | |
| gameObject.name == _previousNames[gameObject]) | |
| { | |
| return; | |
| } | |
| Debug.Log($"GameObject renamed from: {_previousNames[gameObject]} to: {gameObject.name}"); | |
| GameObjectRenamed?.Invoke(gameObject); | |
| _previousNames[gameObject] = gameObject.name; | |
| } | |
| private static void HandleGameObjectAdded(GameObject gameObject) | |
| { | |
| if (_previousNames.ContainsKey(gameObject)) | |
| { | |
| return; | |
| } | |
| Debug.Log($"GameObject added: {gameObject.name}"); | |
| GameObjectAdded?.Invoke(gameObject); | |
| _previousNames.Add(gameObject, gameObject.name); | |
| _previousParents.Add(gameObject, gameObject.transform.parent); | |
| } | |
| private static void HandleGameObjectParentChanged(GameObject gameObject) | |
| { | |
| Transform currentParent = gameObject.transform.parent; | |
| if (!_previousParents.ContainsKey(gameObject) || | |
| currentParent == _previousParents[gameObject]) | |
| { | |
| return; | |
| } | |
| Debug.Log($"GameObject parent changed: {gameObject.name}"); | |
| GameObjectParentChanged?.Invoke(gameObject, _previousParents[gameObject], currentParent); | |
| _previousParents[gameObject] = currentParent; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment