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