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);
}
}
}