using System; using System.Collections.Generic; using UnityEngine; namespace Unity.Linq { public static partial class GameObjectExtensions { /// Returns a collection of GameObjects that contains the ancestors of every GameObject in the source collection. public static IEnumerable Ancestors(this IEnumerable source) { foreach (var item in source) { var e = item.Ancestors().GetEnumerator(); while (e.MoveNext()) { yield return e.Current; } } } /// Returns a collection of GameObjects that contains every GameObject in the source collection, and the ancestors of every GameObject in the source collection. public static IEnumerable AncestorsAndSelf(this IEnumerable source) { foreach (var item in source) { var e = item.AncestorsAndSelf().GetEnumerator(); while (e.MoveNext()) { yield return e.Current; } } } /// Returns a collection of GameObjects that contains the descendant GameObjects of every GameObject in the source collection. public static IEnumerable Descendants(this IEnumerable source, Func descendIntoChildren = null) { foreach (var item in source) { var e = item.Descendants(descendIntoChildren).GetEnumerator(); while (e.MoveNext()) { yield return e.Current; } } } /// Returns a collection of GameObjects that contains every GameObject in the source collection, and the descendent GameObjects of every GameObject in the source collection. public static IEnumerable DescendantsAndSelf(this IEnumerable source, Func descendIntoChildren = null) { foreach (var item in source) { var e = item.DescendantsAndSelf(descendIntoChildren).GetEnumerator(); while (e.MoveNext()) { yield return e.Current; } } } /// Returns a collection of the child GameObjects of every GameObject in the source collection. public static IEnumerable Children(this IEnumerable source) { foreach (var item in source) { var e = item.Children().GetEnumerator(); while (e.MoveNext()) { yield return e.Current; } } } /// Returns a collection of GameObjects that contains every GameObject in the source collection, and the child GameObjects of every GameObject in the source collection. public static IEnumerable ChildrenAndSelf(this IEnumerable source) { foreach (var item in source) { var e = item.ChildrenAndSelf().GetEnumerator(); while (e.MoveNext()) { yield return e.Current; } } } /// Destroy every GameObject in the source collection safety(check null). /// If in EditMode, should be true or pass !Application.isPlaying. /// set to parent = null. public static void Destroy(this IEnumerable source, bool useDestroyImmediate = false, bool detachParent = false) { if (detachParent) { var l = new List(source); // avoid halloween problem var e = l.GetEnumerator(); // get struct enumerator for avoid unity's compiler bug(avoid boxing) while (e.MoveNext()) { e.Current.Destroy(useDestroyImmediate, true); } } else { foreach (var item in source) { item.Destroy(useDestroyImmediate, false); // doesn't detach. } } } /// Returns a collection of specified component in the source collection. public static IEnumerable OfComponent(this IEnumerable source) where T : UnityEngine.Component { foreach (var item in source) { #if UNITY_EDITOR var cache = ComponentCache.Instance; item.GetComponents(cache); if (cache.Count != 0) { var component = cache[0]; cache.Clear(); yield return component; } #else var component = item.GetComponent(); if (component != null) { yield return component; } #endif } } #if UNITY_EDITOR class ComponentCache { public static readonly List Instance = new List(); // for no allocate on UNITY_EDITOR } #endif /// Store element into the buffer, return number is size. array is automaticaly expanded. public static int ToArrayNonAlloc(this IEnumerable source, ref T[] array) { var index = 0; foreach (var item in source) { if (array.Length == index) { var newSize = (index == 0) ? 4 : index * 2; Array.Resize(ref array, newSize); } array[index++] = item; } return index; } } }