초기 커밋.
This commit is contained in:
167
Assets/Scripts/UVC/Linq/GameObjectExtensions.Enumerable.cs
Normal file
167
Assets/Scripts/UVC/Linq/GameObjectExtensions.Enumerable.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UVC.Linq
|
||||
{
|
||||
public static partial class GameObjectExtensions
|
||||
{
|
||||
/// <summary>소스 컬렉션에 있는 모든 GameObject의 조상을 포함하는 GameObject 컬렉션을 반환합니다.</summary>
|
||||
public static IEnumerable<GameObject> Ancestors(this IEnumerable<GameObject> source)
|
||||
{
|
||||
foreach (var item in source)
|
||||
{
|
||||
var e = item.Ancestors().GetEnumerator();
|
||||
while (e.MoveNext())
|
||||
{
|
||||
yield return e.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>소스 컬렉션의 모든 GameObject와 이들의 조상 GameObject를 포함하는 컬렉션을 반환합니다.</summary>
|
||||
public static IEnumerable<GameObject> AncestorsAndSelf(this IEnumerable<GameObject> source)
|
||||
{
|
||||
foreach (var item in source)
|
||||
{
|
||||
var e = item.AncestorsAndSelf().GetEnumerator();
|
||||
while (e.MoveNext())
|
||||
{
|
||||
yield return e.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>소스 컬렉션에 있는 모든 GameObject의 자손 GameObject를 포함하는 컬렉션을 반환합니다.</summary>
|
||||
/// <param name="descendIntoChildren">자식 객체를 순회할지 결정하는 조건 함수입니다. null이면 모든 자식을 순회합니다.</param>
|
||||
public static IEnumerable<GameObject> Descendants(this IEnumerable<GameObject> source, Func<Transform, bool> descendIntoChildren = null)
|
||||
{
|
||||
foreach (var item in source)
|
||||
{
|
||||
var e = item.Descendants(descendIntoChildren).GetEnumerator();
|
||||
while (e.MoveNext())
|
||||
{
|
||||
yield return e.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>소스 컬렉션의 모든 GameObject와 이들의 자손 GameObject를 포함하는 컬렉션을 반환합니다.</summary>
|
||||
public static IEnumerable<GameObject> DescendantsAndSelf(this IEnumerable<GameObject> source, Func<Transform, bool> descendIntoChildren = null)
|
||||
{
|
||||
foreach (var item in source)
|
||||
{
|
||||
var e = item.DescendantsAndSelf(descendIntoChildren).GetEnumerator();
|
||||
while (e.MoveNext())
|
||||
{
|
||||
yield return e.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>소스 컬렉션에 있는 모든 GameObject의 자식 GameObject를 포함하는 컬렉션을 반환합니다.</summary>
|
||||
public static IEnumerable<GameObject> Children(this IEnumerable<GameObject> source)
|
||||
{
|
||||
foreach (var item in source)
|
||||
{
|
||||
var e = item.Children().GetEnumerator();
|
||||
while (e.MoveNext())
|
||||
{
|
||||
yield return e.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>소스 컬렉션의 모든 GameObject와 이들의 자식 GameObject를 포함하는 컬렉션을 반환합니다.</summary>
|
||||
public static IEnumerable<GameObject> ChildrenAndSelf(this IEnumerable<GameObject> source)
|
||||
{
|
||||
foreach (var item in source)
|
||||
{
|
||||
var e = item.ChildrenAndSelf().GetEnumerator();
|
||||
while (e.MoveNext())
|
||||
{
|
||||
yield return e.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>소스 컬렉션에 있는 모든 GameObject를 안전하게(null 체크 포함) 파괴합니다.</summary>
|
||||
/// <param name="useDestroyImmediate">에디터 모드에서는 true로 설정하거나 !Application.isPlaying을 전달하세요.</param>
|
||||
/// <param name="detachParent">부모를 null로 설정합니다.</param>
|
||||
public static void Destroy(this IEnumerable<GameObject> source, bool useDestroyImmediate = false, bool detachParent = false)
|
||||
{
|
||||
if (detachParent)
|
||||
{
|
||||
var l = new List<GameObject>(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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>소스 컬렉션에서 지정된 컴포넌트 타입의 컬렉션을 반환합니다.</summary>
|
||||
/// <typeparam name="T">검색할 컴포넌트의 타입입니다.</typeparam>
|
||||
/// <remarks>에디터 모드에서는 메모리 할당을 최소화하기 위한 캐시 메커니즘을 사용합니다.</remarks>
|
||||
public static IEnumerable<T> OfComponent<T>(this IEnumerable<GameObject> source)
|
||||
where T : UnityEngine.Component
|
||||
{
|
||||
foreach (var item in source)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var cache = ComponentCache<T>.Instance;
|
||||
item.GetComponents<T>(cache);
|
||||
if (cache.Count != 0)
|
||||
{
|
||||
var component = cache[0];
|
||||
cache.Clear();
|
||||
yield return component;
|
||||
}
|
||||
#else
|
||||
|
||||
var component = item.GetComponent<T>();
|
||||
if (component != null)
|
||||
{
|
||||
yield return component;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
class ComponentCache<T>
|
||||
{
|
||||
public static readonly List<T> Instance = new List<T>(); // for no allocate on UNITY_EDITOR
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>요소를 버퍼에 저장하고, 크기를 반환합니다. 배열은 자동으로 확장됩니다.</summary>
|
||||
/// <param name="source">저장할 요소들의 소스 컬렉션입니다.</param>
|
||||
/// <param name="array">요소를 저장할 배열 참조입니다. 필요에 따라 크기가 조정됩니다.</param>
|
||||
/// <returns>배열에 저장된 요소의 수를 반환합니다.</returns>
|
||||
public static int ToArrayNonAlloc<T>(this IEnumerable<T> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user