< Summary

Class:GDX.TransformExtensions
Assembly:GDX
File(s):D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/TransformExtensions.cs
Covered lines:45
Uncovered lines:10
Coverable lines:55
Total lines:150
Line coverage:81.8% (45 of 55)
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.126085%
GetActiveChildCount(...)0%330100%
GetFirstComponentInChildrenComplex[T](...)0%17.2410058.33%
GetScenePath(...)0%4.014092.31%

File(s)

D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/TransformExtensions.cs

#LineLine coverage
 1// Copyright (c) 2020-2022 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 UnityEngine;
 10
 11namespace GDX
 12{
 13    /// <summary>
 14    ///     <see cref="UnityEngine.Transform" /> Based Extension Methods
 15    /// </summary>
 16    /// <exception cref="UnsupportedRuntimeException">Not supported on DOTS Runtime.</exception>
 17    [VisualScriptingCompatible(2)]
 18    public static class TransformExtensions
 19    {
 20        /// <summary>
 21        ///     Destroy child <see cref="Transform" />.
 22        /// </summary>
 23        /// <param name="targetTransform">The parent <see cref="Transform" /> to look at.</param>
 24        /// <param name="deactivateBeforeDestroy">
 25        ///     Should the <paramref name="targetTransform" /> children's
 26        ///     <see cref="GameObject" />s be deactivated before destroying? This can be used to immediately hide an obj
 27        ///     will be destroyed at the end of the frame.
 28        /// </param>
 29        /// <param name="destroyInactive">Should inactive <see cref="GameObject" /> be destroyed as well?</param>
 30        /// <param name="immediateMode">Should the destroy be done immediately? This is useful for author time calls.</p
 31        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 32        public static void DestroyChildren(this Transform targetTransform, bool deactivateBeforeDestroy = true,
 33            bool destroyInactive = true, bool immediateMode = false)
 234        {
 235            int count = targetTransform.childCount;
 1636            for (int i = count - 1; i >= 0; i--)
 637            {
 638                GameObject childObject = targetTransform.GetChild(i).gameObject;
 739                if (!destroyInactive && !childObject.activeInHierarchy) continue;
 40
 841                if (deactivateBeforeDestroy) childObject.SetActive(false);
 42
 543                if (immediateMode)
 544                {
 545                    Object.DestroyImmediate(childObject);
 546                }
 47                else
 048                {
 049                    Object.Destroy(childObject);
 050                }
 551            }
 252        }
 53
 54        /// <summary>
 55        ///     Get the number of immediate children active.
 56        /// </summary>
 57        /// <param name="targetTransform">The transform to look at's children.</param>
 58        /// <returns>The number of active children transforms.</returns>
 59        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 60        public static int GetActiveChildCount(this Transform targetTransform)
 161        {
 162            int counter = 0;
 163            int childCount = targetTransform.childCount;
 864            for (int i = 0; i < childCount; i++)
 365                if (targetTransform.GetChild(i).gameObject.activeSelf)
 266                    counter++;
 67
 168            return counter;
 169        }
 70
 71        /// <summary>
 72        ///     Search recursively for a <see cref="Component" /> on the <paramref name="targetTransform" />.
 73        /// </summary>
 74        /// <param name="targetTransform">The target <see cref="Transform" /> to use as the base for the search.</param>
 75        /// <param name="includeInactive">
 76        ///     Include inactive child <see cref="GameObject" />s when looking for the
 77        ///     <see cref="Component" />.
 78        /// </param>
 79        /// <param name="currentDepth">Current level of recursion.</param>
 80        /// <param name="maxLevelsOfRecursion">
 81        ///     The maximum levels of recursion when looking for a <see cref="Component" />, -1 for
 82        ///     infinite recursion.
 83        /// </param>
 84        /// <typeparam name="T">The target <see cref="UnityEngine.Component" /> type that is being looked for.</typepara
 85        /// <returns>The first found <see cref="Component" />.</returns>
 86        public static T GetFirstComponentInChildrenComplex<T>(this Transform targetTransform, bool includeInactive,
 87            int currentDepth, int maxLevelsOfRecursion)
 188        {
 89            // Make sure we have nothing to return if necessary.
 190            T returnComponent = default;
 91
 92            // Increase depth count
 193            currentDepth++;
 94
 195            if (maxLevelsOfRecursion >= 0 && currentDepth > maxLevelsOfRecursion) return returnComponent;
 96
 197            int cachedChildCount = targetTransform.childCount;
 298            for (int i = 0; i < cachedChildCount; i++)
 199            {
 1100                Transform transformToCheck = targetTransform.GetChild(i);
 101
 102                // Don't include disabled transforms
 1103                if (!transformToCheck.gameObject.activeSelf &&
 104                    !includeInactive)
 0105                    continue;
 106
 107                // Lets check the current transform for the component.
 1108                returnComponent = transformToCheck.GetComponent<T>();
 2109                if (returnComponent != null) return returnComponent;
 110
 111                // OK, time to deep dive.
 0112                if (maxLevelsOfRecursion >= 0 && currentDepth >= maxLevelsOfRecursion) continue;
 113
 0114                returnComponent = GetFirstComponentInChildrenComplex<T>(transformToCheck, includeInactive, currentDepth,
 115                    maxLevelsOfRecursion);
 0116                if (returnComponent != null) return returnComponent;
 0117            }
 118
 0119            return returnComponent;
 1120        }
 121
 122        /// <summary>
 123        ///     Get an in scene path to the <paramref name="targetTransform" />.
 124        /// </summary>
 125        /// <param name="targetTransform">The <see cref="Transform" /> which to derive a path from.</param>
 126        /// <returns>A created path <see cref="System.String" />.</returns>
 127        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 128        public static string GetScenePath(this Transform targetTransform)
 1129        {
 1130            StringBuilder stringBuilder = new StringBuilder();
 131#if UNITY_EDITOR
 1132            Transform originalTransform = targetTransform;
 133#endif
 2134            while (targetTransform != null)
 1135            {
 1136                stringBuilder.Insert(0, targetTransform.name);
 1137                stringBuilder.Insert(0, '/');
 1138                targetTransform = targetTransform.parent;
 1139            }
 140#if UNITY_EDITOR
 1141            if (originalTransform &&
 142                UnityEditor.EditorUtility.IsPersistent(originalTransform))
 0143                stringBuilder.Append(" [P]");
 144#endif
 1145            return stringBuilder.ToString();
 1146        }
 147    }
 148}
 149// ReSharper disable once CommentTypo
 150#endif // !UNITY_DOTSRUNTIME