using UnityEngine;
namespace X10D.Unity;
///
/// Extension methods for .
///
public static class GameObjectExtensions
{
///
/// Returns an array of components of the specified type, excluding components that live on this game object.
///
/// The game object whose child components to retrieve.
/// The type of the components to retrieve.
/// An array representing the child components.
/// is .
public static T[] GetComponentsInChildrenOnly(this GameObject gameObject)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
Transform rootTransform = gameObject.transform;
var components = new List(gameObject.GetComponentsInChildren());
for (var index = 0; index < components.Count; index++)
{
if (components[index] is not Component childComponent)
{
// this shouldn't happen, since you can't add a non-Component to a game object,
// but GetComponentsInChildren is not constrained, so this method shouldn't be either
continue;
}
if (childComponent.transform == rootTransform)
{
components.RemoveAt(index);
index--;
}
}
return components.ToArray();
}
///
/// Rotates the transform component of this game object so the forward vector points at another game object.
///
/// The game object whose rotation will be changed.
/// The game object to look at.
///
/// is .
/// -or-
/// is .
///
public static void LookAt(this GameObject gameObject, GameObject target)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
gameObject.transform.LookAt(target.transform);
}
///
/// Rotates the transform component of this game object so the forward vector points at .
///
/// The game object whose rotation will be changed.
/// The point to look at.
/// is .
public static void LookAt(this GameObject gameObject, Vector3 target)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
gameObject.transform.LookAt(target);
}
///
/// Rotates the transform component of this game object so the forward vector points at a specified transform.
///
/// The game object whose rotation will be changed.
/// The transform to look at.
///
/// is .
/// -or-
/// is .
///
public static void LookAt(this GameObject gameObject, Transform target)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
gameObject.transform.LookAt(target);
}
///
/// Rotates the transform component of this game object so the forward vector points at another game object.
///
/// The game object whose rotation will be changed.
/// The game object to look at.
/// A vector specifying the upward direction.
///
/// is .
/// -or-
/// is .
///
public static void LookAt(this GameObject gameObject, GameObject target, Vector3 worldUp)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
gameObject.transform.LookAt(target.transform, worldUp);
}
///
/// Rotates the transform component of this game object so the forward vector points at .
///
/// The game object whose rotation will be changed.
/// The point to look at.
/// A vector specifying the upward direction.
/// is .
public static void LookAt(this GameObject gameObject, Vector3 target, Vector3 worldUp)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
gameObject.transform.LookAt(target, worldUp);
}
///
/// Rotates the transform component of this game object so the forward vector points at a specified transform.
///
/// The game object whose rotation will be changed.
/// The transform to look at.
/// A vector specifying the upward direction.
///
/// is .
/// -or-
/// is .
///
public static void LookAt(this GameObject gameObject, Transform target, Vector3 worldUp)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
gameObject.transform.LookAt(target, worldUp);
}
///
/// Sets the new layer of this game object and its children, recursively.
///
/// The game object whose layer, and that of its children recursively, to change.
/// The new layer.
/// is .
public static void SetLayerRecursively(this GameObject gameObject, int layer)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
var children = new Stack();
var transform = gameObject.transform;
children.Push(transform);
while (children.Count > 0)
{
Transform child = children.Pop();
int childCount = child.childCount;
child.gameObject.layer = layer;
if (childCount <= 0)
{
continue;
}
for (var childIndex = 0; childIndex < childCount; childIndex++)
{
children.Push(child.GetChild(childIndex));
}
}
}
///
/// Sets the parent of this game object.
///
/// The game object whose parent to change.
/// The new parent.
///
/// is .
/// -or-
/// is .
///
public static void SetParent(this GameObject gameObject, GameObject parent)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (parent == null)
{
throw new ArgumentNullException(nameof(parent));
}
gameObject.transform.SetParent(parent.transform);
}
///
/// Sets the parent of this game object.
///
/// The game object whose parent to change.
/// The new parent.
///
/// is .
/// -or-
/// is .
///
public static void SetParent(this GameObject gameObject, Transform parent)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (parent == null)
{
throw new ArgumentNullException(nameof(parent));
}
gameObject.transform.SetParent(parent);
}
///
/// Sets the parent of this game object.
///
/// The game object whose parent to change.
/// The new parent.
///
/// to modify the parent-relative position, scale and rotation such that the object keeps the same
/// world space position, rotation and scale as before; otherwise, .
///
///
/// is .
/// -or-
/// is .
///
public static void SetParent(this GameObject gameObject, GameObject parent, bool worldPositionStays)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (parent == null)
{
throw new ArgumentNullException(nameof(parent));
}
gameObject.transform.SetParent(parent.transform, worldPositionStays);
}
///
/// Sets the parent of this game object.
///
/// The game object whose parent to change.
/// The new parent.
///
/// to modify the parent-relative position, scale and rotation such that the object keeps the same
/// world space position, rotation and scale as before; otherwise, .
///
///
/// is .
/// -or-
/// is .
///
public static void SetParent(this GameObject gameObject, Transform parent, bool worldPositionStays)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
if (parent == null)
{
throw new ArgumentNullException(nameof(parent));
}
gameObject.transform.SetParent(parent, worldPositionStays);
}
}