Files
XRLib/Assets/Scripts/UVC/Extention/TransformEx.cs

215 lines
8.0 KiB
C#

#nullable enable
using UnityEngine;
namespace UVC.Extension
{
/// <summary>
/// Transform 클래스에 대한 확장 메소드를 제공하는 정적 클래스입니다.
/// </summary>
public static class TransformEx
{
/// <summary>
/// 하위 자식까지 확인해서 이름이 같은 오브젝트를 찾는다.
/// </summary>
/// <param name="t">검색을 시작할 부모 Transform</param>
/// <param name="name">찾고자 하는 자식 GameObject의 이름</param>
/// <returns>찾은 자식 Transform 또는 찾지 못한 경우 null</returns>
/// <example>
/// <code>
/// // 사용 예시
/// Transform parentTransform = gameObject.transform;
/// Transform childTransform = parentTransform.FindChildren("TargetChild");
///
/// if (childTransform != null)
/// {
/// // 찾은 자식 오브젝트 사용
/// childTransform.gameObject.SetActive(true);
/// }
/// </code>
/// </example>
public static Transform? FindChildren(this Transform t, string name)
{
Transform? child = null;
var children = t.GetComponentsInChildren<Transform>(true);
int len = children.Length;
//첫번째 자식은 자기 자신이므로 제외
for (int i = 1; i < len; i++)
{
Transform c = children[i];
if (c.name == name)
{
child = c;
break;
}
}
return child;
}
/// <summary>
/// 직계 자식 Transform을 반환합니다.
/// </summary>
/// <param name="t">직계 자식을 검색할 변환입니다. <see langword="null"/>일 수 없습니다.</param>
/// <returns>지정된 변환의 직계 자식을 나타내는 <see cref="Transform"/> 객체의 배열입니다.
/// 변환에 자식이 없으면 배열은 비어 있습니다.</returns>
public static Transform[] GetChildren(this Transform t)
{
Transform[] children = new Transform[t.childCount];
for (int i = 0; i < t.childCount; i++)
{
children[i] = t.GetChild(i);
}
return children;
}
/// <summary>
/// 직계 자식에서 T를 찾아 반환합니다.
/// </summary>
/// <typeparam name="T">검색할 구성 요소의 유형입니다. <see cref="MonoBehaviour"/>에서 파생되어야 합니다.</typeparam>
/// <param name="t">자식 구성 요소를 검색할 변환입니다.</param>
/// <returns>변환의 자식에서 발견된 <typeparamref name="T"/> 유형의 구성 요소 배열입니다. 자식에
/// <typeparamref name="T"/> 유형의 구성 요소가 없는 경우 해당 배열 항목은 <see
/// langword="null"/>입니다.</returns>
public static T[] GetChildren<T>(this Transform t) where T : Component
{
T[] children = new T[t.childCount];
for (int i = 0; i < t.childCount; i++)
{
var temp = t.GetChild(i).GetComponent<T>();
if(temp != null) children[i] = temp;
}
return children;
}
/// <summary>
/// Transform의 X 좌표만 변경합니다.
/// </summary>
/// <param name="t">대상 Transform</param>
/// <param name="x">설정할 X 좌표 값</param>
/// <returns>변경된 Transform (메소드 체이닝 지원)</returns>
/// <example>
/// <code>
/// // 사용 예시
/// transform.SetPositionX(5f).SetPositionZ(3f);
/// </code>
/// </example>
public static Transform SetPositionX(this Transform t, float x)
{
Vector3 position = t.position;
position.x = x;
t.position = position;
return t;
}
/// <summary>
/// Transform의 Y 좌표만 변경합니다.
/// </summary>
/// <param name="t">대상 Transform</param>
/// <param name="y">설정할 Y 좌표 값</param>
/// <returns>변경된 Transform (메소드 체이닝 지원)</returns>
/// <example>
/// <code>
/// // 사용 예시
/// transform.SetPositionY(5f).SetPositionZ(3f);
/// </code>
/// </example>
public static Transform SetPositionY(this Transform t, float y)
{
Vector3 position = t.position;
position.y = y;
t.position = position;
return t;
}
/// <summary>
/// Transform의 Z 좌표만 변경합니다.
/// </summary>
/// <param name="t">대상 Transform</param>
/// <param name="z">설정할 Z 좌표 값</param>
/// <returns>변경된 Transform (메소드 체이닝 지원)</returns>
/// <example>
/// <code>
/// // 사용 예시
/// transform.SetPositionX(5f).SetPositionZ(3f);
/// </code>
/// </example>
public static Transform SetPositionZ(this Transform t, float z)
{
Vector3 position = t.position;
position.z = z;
t.position = position;
return t;
}
/// <summary>
/// 하위 자식 중에서 특정 태그를 가진 오브젝트를 모두 찾습니다.
/// </summary>
/// <param name="t">검색을 시작할 부모 Transform</param>
/// <param name="tag">찾고자 하는 태그</param>
/// <returns>찾은 Transform 배열</returns>
/// <example>
/// <code>
/// // 사용 예시
/// Transform[] enemies = parentTransform.FindChildrenWithTag("Enemy");
/// foreach (Transform enemy in enemies)
/// {
/// // 찾은 적 오브젝트 처리
/// enemy.gameObject.SetActive(false);
/// }
/// </code>
/// </example>
public static Transform[] FindChildrenWithTag(this Transform t, string tag)
{
System.Collections.Generic.List<Transform> result = new System.Collections.Generic.List<Transform>();
FindChildrenWithTagRecursive(t, tag, result);
return result.ToArray();
}
private static void FindChildrenWithTagRecursive(Transform parent, string tag, System.Collections.Generic.List<Transform> result)
{
int childCount = parent.childCount;
for (int i = 0; i < childCount; i++)
{
Transform child = parent.GetChild(i);
if (child.CompareTag(tag))
{
result.Add(child);
}
FindChildrenWithTagRecursive(child, tag, result);
}
}
/// <summary>
/// Transform을 기본 상태로 초기화합니다. (위치: 원점, 회전: 0, 크기: 1)
/// </summary>
/// <param name="t">초기화할 Transform</param>
/// <returns>초기화된 Transform (메소드 체이닝 지원)</returns>
/// <example>
/// <code>
/// // 사용 예시
/// transform.ResetTransform();
/// </code>
/// </example>
public static Transform ResetTransform(this Transform t)
{
t.localPosition = Vector3.zero;
t.localRotation = Quaternion.identity;
t.localScale = Vector3.one;
return t;
}
/// <summary>
/// 지정된 <see cref="Transform"/>의 로컬 위치를 월드 공간 좌표로 변환합니다.
/// </summary>
/// <param name="t">로컬 위치를 변환할 <see cref="Transform"/>입니다.</param>
/// <returns> <paramref name="t"/> 로컬 위치의 월드 공간 좌표를 나타내는 <see cref="Vector3"/>입니다.</returns>
public static Vector3 ToWorldPosition(this Transform t)
{
return t.TransformPoint(t.localPosition);
}
}
}