< Summary

Class:GDX.TransformExtensions
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/TransformExtensions.cs
Covered lines:67
Uncovered lines:7
Coverable lines:74
Total lines:176
Line coverage:90.5% (67 of 74)
Covered branches:0
Total branches:0
Covered methods:4
Total methods:4
Method coverage:100% (4 of 4)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
DestroyChildren(...)0%6.376078.26%
GetActiveChildCount(...)0%330100%
GetFirstComponentInChildrenComplex[T](...)0%10.9810078.57%
GetScenePath(...)0%4.134080%

File(s)

./Packages/com.dotbunny.gdx/GDX/TransformExtensions.cs

#LineLine coverage
 1// Copyright (c) 2020-2024 dotBunny Inc.
 2// dotBunny licenses this file to you under the BSL-1.0 license.
 3// See the LICENSE file in the project root for more information.
 4
 5#if !UNITY_DOTSRUNTIME
 6
 7using System.Runtime.CompilerServices;
 8using System.Text;
 9using UnityEditor;
 10using UnityEngine;
 11
 12namespace GDX
 13{
 14    /// <summary>
 15    ///     <see cref="UnityEngine.Transform" /> Based Extension Methods
 16    /// </summary>
 17    /// <exception cref="UnsupportedRuntimeException">Not supported on DOTS Runtime.</exception>
 18    [VisualScriptingCompatible(2)]
 19    public static class TransformExtensions
 20    {
 21        /// <summary>
 22        ///     Destroy child <see cref="Transform" />.
 23        /// </summary>
 24        /// <param name="targetTransform">The parent <see cref="Transform" /> to look at.</param>
 25        /// <param name="deactivateBeforeDestroy">
 26        ///     Should the <paramref name="targetTransform" /> children's
 27        ///     <see cref="GameObject" />s be deactivated before destroying? This can be used to immediately hide an obj
 28        ///     will be destroyed at the end of the frame.
 29        /// </param>
 30        /// <param name="destroyInactive">Should inactive <see cref="GameObject" /> be destroyed as well?</param>
 31        /// <param name="immediateMode">Should the destroy be done immediately? This is useful for author time calls.</p
 32        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 33        public static void DestroyChildren(this Transform targetTransform, bool deactivateBeforeDestroy = true,
 34            bool destroyInactive = true, bool immediateMode = false)
 335        {
 336            int count = targetTransform.childCount;
 2437            for (int i = count - 1; i >= 0; i--)
 938            {
 939                GameObject childObject = targetTransform.GetChild(i).gameObject;
 940                if (!destroyInactive && !childObject.activeInHierarchy)
 241                {
 242                    continue;
 43                }
 44
 745                if (deactivateBeforeDestroy)
 346                {
 347                    childObject.SetActive(false);
 348                }
 49
 750                if (immediateMode)
 551                {
 552                    Object.DestroyImmediate(childObject);
 553                }
 54                else
 255                {
 256                    Object.Destroy(childObject);
 257                }
 758            }
 359        }
 60
 61        /// <summary>
 62        ///     Get the number of immediate children active.
 63        /// </summary>
 64        /// <param name="targetTransform">The transform to look at's children.</param>
 65        /// <returns>The number of active children transforms.</returns>
 66        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 67        public static int GetActiveChildCount(this Transform targetTransform)
 168        {
 169            int counter = 0;
 170            int childCount = targetTransform.childCount;
 871            for (int i = 0; i < childCount; i++)
 372            {
 373                if (targetTransform.GetChild(i).gameObject.activeSelf)
 274                {
 275                    counter++;
 276                }
 377            }
 78
 179            return counter;
 180        }
 81
 82        /// <summary>
 83        ///     Search recursively for a <see cref="Component" /> on the <paramref name="targetTransform" />.
 84        /// </summary>
 85        /// <param name="targetTransform">The target <see cref="Transform" /> to use as the base for the search.</param>
 86        /// <param name="includeInactive">
 87        ///     Include inactive child <see cref="GameObject" />s when looking for the
 88        ///     <see cref="Component" />.
 89        /// </param>
 90        /// <param name="currentDepth">Current level of recursion.</param>
 91        /// <param name="maxLevelsOfRecursion">
 92        ///     The maximum levels of recursion when looking for a <see cref="Component" />, -1 for
 93        ///     infinite recursion.
 94        /// </param>
 95        /// <typeparam name="T">The target <see cref="UnityEngine.Component" /> type that is being looked for.</typepara
 96        /// <returns>The first found <see cref="Component" />.</returns>
 97        public static T GetFirstComponentInChildrenComplex<T>(this Transform targetTransform, bool includeInactive,
 98            int currentDepth, int maxLevelsOfRecursion = -1) where T : Component
 699        {
 100            // Increase depth count
 6101            currentDepth++;
 102
 6103            if (maxLevelsOfRecursion >= 0 && currentDepth > maxLevelsOfRecursion)
 0104            {
 0105                return default;
 106            }
 107
 6108            int cachedChildCount = targetTransform.childCount;
 20109            for (int i = 0; i < cachedChildCount; i++)
 8110            {
 8111                Transform transformToCheck = targetTransform.GetChild(i);
 112
 113                // Don't include disabled transforms
 8114                if (!transformToCheck.gameObject.activeSelf &&
 115                    !includeInactive)
 0116                {
 0117                    continue;
 118                }
 119
 120                // Lets check the current transform for the component.
 8121                T returnComponent = transformToCheck.GetComponent<T>();
 122
 123                // Its important to use the Equals here, not a !=
 8124                if (returnComponent != null)
 3125                {
 3126                    return returnComponent;
 127                }
 128
 129                // OK, time to deep dive.
 5130                if (maxLevelsOfRecursion >= 0 && currentDepth >= maxLevelsOfRecursion)
 2131                {
 2132                    continue;
 133                }
 134
 3135                returnComponent = GetFirstComponentInChildrenComplex<T>(transformToCheck, includeInactive, currentDepth,
 136                    maxLevelsOfRecursion);
 3137                if (returnComponent != null)
 1138                {
 1139                    return returnComponent;
 140                }
 2141            }
 142
 2143            return default;
 6144        }
 145
 146        /// <summary>
 147        ///     Get an in scene path to the <paramref name="targetTransform" />.
 148        /// </summary>
 149        /// <param name="targetTransform">The <see cref="Transform" /> which to derive a path from.</param>
 150        /// <returns>A created path <see cref="System.String" />.</returns>
 151        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 152        public static string GetScenePath(this Transform targetTransform)
 1153        {
 1154            StringBuilder stringBuilder = new StringBuilder();
 155#if UNITY_EDITOR
 1156            Transform originalTransform = targetTransform;
 157#endif // UNITY_EDITOR
 2158            while (targetTransform != null)
 1159            {
 1160                stringBuilder.Insert(0, targetTransform.name);
 1161                stringBuilder.Insert(0, '/');
 1162                targetTransform = targetTransform.parent;
 1163            }
 164#if UNITY_EDITOR
 1165            if (originalTransform &&
 166                EditorUtility.IsPersistent(originalTransform))
 0167            {
 0168                stringBuilder.Append(" [P]");
 0169            }
 170#endif // UNITY_EDITOR
 1171            return stringBuilder.ToString();
 1172        }
 173    }
 174}
 175// ReSharper disable once CommentTypo
 176#endif // !UNITY_DOTSRUNTIME

Coverage by test methods









































Methods/Properties

DestroyChildren(UnityEngine.Transform, System.Boolean, System.Boolean, System.Boolean)
GetActiveChildCount(UnityEngine.Transform)
GetFirstComponentInChildrenComplex[T](UnityEngine.Transform, System.Boolean, System.Int32, System.Int32)
GetScenePath(UnityEngine.Transform)