using System; using JetBrains.Annotations; using UnityEngine; namespace Core.Extensions { public static class GameObjectExtensions { /// /// Sets the layer for this game object and all its children /// public static void SetLayerRecursively(this GameObject gameObject, int layer) { gameObject.layer = layer; // Non recursive, non allocating traversal Transform goTransform = gameObject.transform; if (goTransform.childCount > 0) { WalkHeirarchyAndSetLayer(goTransform, layer); } } /// /// Walks the heirarchy from , look at all its children and change the layer. /// Non-allocating and non-recursive /// /// The root object to start our search from /// The layer to set the game object too static void WalkHeirarchyAndSetLayer([NotNull] Transform root, int layer) { if (root.childCount == 0) { throw new InvalidOperationException("Root transform has no children"); } Transform workingTransform = root.GetChild(0); // Work until we get back to the root while (workingTransform != root) { // Change layer workingTransform.gameObject.layer = layer; // Get children if we have if (workingTransform.childCount > 0) { workingTransform = workingTransform.GetChild(0); } // No children, look for siblings else { // Set to our sibling if (!TryGetNextSibling(ref workingTransform)) { // Otherwise walk up parents and find THEIR next sibling workingTransform = workingTransform.parent; while (workingTransform != root && !TryGetNextSibling(ref workingTransform)) { workingTransform = workingTransform.parent; } } } } } /// /// Tries to advance to a sibling of /// /// The transform whose siblings we're looking for /// True if we had a sibling. will now refer to it. static bool TryGetNextSibling([NotNull] ref Transform transform) { Transform parent = transform.parent; int siblingIndex = transform.GetSiblingIndex(); // Get siblings if we don't have children if (parent.childCount > siblingIndex + 1) { transform = parent.GetChild(siblingIndex + 1); return true; } return false; } } }