namespace Zinnia.Extension { using System; using System.Collections.Generic; using UnityEngine; /// /// Extended methods for the Type. /// public static class GameObjectExtensions { #if UNITY_EDITOR private static class ComponentCache where T : Component { public static readonly List List = new List(); } #endif /// /// Attempts to set the active state. /// /// The to set the active state on. /// The new state. public static void TrySetActive(this GameObject gameObject, bool state) { if (gameObject != null) { gameObject.SetActive(state); } } /// /// Attempts to retrieve the component or if one is not found then optionally search children then search parents for the component. /// /// The type of the component to retrieve. /// The reference to search on. /// Optionally searches all ancestors in the hierarchy for the component. /// Optionally searches all descendants in the hierarchy for component. /// The component if one exists. public static T TryGetComponent(this GameObject gameObject, bool searchDescendants = false, bool searchAncestors = false) where T : Component { if (gameObject == null) { return default; } #if UNITY_EDITOR gameObject.GetComponents(ComponentCache.List); T foundComponent = ComponentCache.List.Count > 0 ? ComponentCache.List[0] : null; #else T foundComponent = gameObject.GetComponent(); #endif if (foundComponent == null && searchDescendants) { #if UNITY_EDITOR gameObject.GetComponentsInChildren(ComponentCache.List); foundComponent = ComponentCache.List.Count > 0 ? ComponentCache.List[0] : null; #else foundComponent = gameObject.GetComponentInChildren(); #endif } if (foundComponent == null && searchAncestors) { #if UNITY_EDITOR gameObject.GetComponentsInParent(false, ComponentCache.List); foundComponent = ComponentCache.List.Count > 0 ? ComponentCache.List[0] : null; #else foundComponent = gameObject.GetComponentInParent(); #endif } return foundComponent; } /// /// Attempts to retrieve the component or if one is not found then optionally search children then search parents for the component. /// /// The reference to search on. /// Optionally searches all ancestors in the hierarchy for the component. /// The /// Optionally searches all descendants in the hierarchy for component. /// The component if one exists. public static Component TryGetComponent(this GameObject gameObject, Type type, bool searchDescendants = false, bool searchAncestors = false) { if (gameObject == null) { return default; } #if UNITY_EDITOR gameObject.GetComponents(type, ComponentCache.List); Component foundComponent = ComponentCache.List.Count > 0 ? ComponentCache.List[0] : null; #else Component foundComponent = gameObject.GetComponent(type); #endif if (foundComponent == null && searchDescendants) { #if UNITY_EDITOR // Unity doesn't offer an overload that works with a non-generic List and passing the type... gameObject.GetComponentsInChildren(ComponentCache.List); // ...so let's find it ourselves. foreach (Component component in ComponentCache.List) { if (type.IsInstanceOfType(component)) { foundComponent = component; break; } } #else foundComponent = gameObject.GetComponentInChildren(type); #endif } if (foundComponent == null && searchAncestors) { #if UNITY_EDITOR // Unity doesn't offer an overload that works with a non-generic List and passing the type... gameObject.GetComponentsInParent(false, ComponentCache.List); // ...so let's find it ourselves. foreach (Component component in ComponentCache.List) { if (type.IsInstanceOfType(component)) { foundComponent = component; break; } } #else foundComponent = gameObject.GetComponentInParent(type); #endif } return foundComponent; } /// /// Attempts to retrieve the position of the . /// /// The reference to retrieve for. /// Determines whether to get the local or world position. /// The position of the . public static Vector3 TryGetPosition(this GameObject gameObject, bool getLocal = false) { return (gameObject != null ? (getLocal ? gameObject.transform.localPosition : gameObject.transform.position) : Vector3.zero); } /// /// Attempts to retrieve the rotation of the . /// /// The reference to retrieve for. /// Determines whether to get the local or world rotation. /// The rotation of the . public static Quaternion TryGetRotation(this GameObject gameObject, bool getLocal = false) { return (gameObject != null ? (getLocal ? gameObject.transform.localRotation : gameObject.transform.rotation) : Quaternion.identity); } /// /// Attempts to retrieve the euler rotation of the . /// /// The reference to retrieve for. /// Determines whether to get the local or world euler rotation. /// The euler rotation of the . public static Vector3 TryGetEulerRotation(this GameObject gameObject, bool getLocal = false) { return (gameObject != null ? (getLocal ? gameObject.transform.localEulerAngles : gameObject.transform.eulerAngles) : Vector3.zero); } /// /// Attempts to retrieve the scale of the . /// /// The reference to retrieve for. /// Determines whether to get the local or world scale. /// The scale of the . public static Vector3 TryGetScale(this GameObject gameObject, bool getLocal = false) { return (gameObject != null ? (getLocal ? gameObject.transform.localScale : gameObject.transform.lossyScale) : Vector3.zero); } } }