This repository has been archived on 2025-09-23. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
XericLibrary-OLD/Runtime/MicroLibrary/MacroObject.cs
T
2023-11-08 13:41:11 +08:00

289 lines
7.9 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace XericLibrary.Runtime.MacroLibrary
{
public static class MacroObject
{
#region 对象操作
/// <summary>
/// 获取此枚举器在给定索引下的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="target"></param>
/// <param name="index"></param>
/// <returns></returns>
/// <exception cref="IndexOutOfRangeException"></exception>
public static T SelectIndex<T>(this IEnumerable<T> target, int index)
{
int nowIndex = 0;
foreach(var item in target)
if(nowIndex++ == index)
return (T)item;
throw new IndexOutOfRangeException("给定的索引超出了枚举器的范围");
}
/// <summary>
/// 获取此枚举器在给定索引下的值,并且允许在无法找到的情况下使用null返回
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="target"></param>
/// <param name="index"></param>
/// <returns></returns>
public static T SelectIndexOrDefault<T>(this IEnumerable<T> target, int index)
where T : class
{
int nowIndex = 0;
foreach(var item in target)
if(nowIndex++ == index)
return (T)item;
return null;
}
/// <summary>
/// 按顺序获取一个节点的所有父级节点
/// </summary>
/// <param name="trans"></param>
/// <returns></returns>
public static IEnumerable<Transform> GetParents(this Transform trans)
{
Transform target = trans.parent;
while(target != null)
{
yield return target;
target = target.parent;
}
}
/// <summary>
/// 遍历项目中父级内所有子项的差距,并找到第1个差距最大的项目;
/// <code>
/// 具体是先从当前节点向上级找到第一个最少子项数量的节点,
/// 以此为基准,从当前最少数量节点的子集中返回来自项目的父级(或来自项目);
/// 具体是用来在场景中寻找第一个具有标识意义的节点
/// </code>
/// </summary>
/// <param name="trans"></param>
/// <param name="backStep">倒数步骤数,基于基准父级/param>
/// <returns></returns>
[Obsolete("未验证的,谨慎使用")]
public static Transform GetObjectNameInParentsFilterByChildrenMeanDifferen(this Transform trans, int backStep = 1)
{
int minParentIndex = 0;
int index = 0;
int minChildCount = int.MaxValue;
foreach(Transform parent in trans.GetParents())
{
if(parent.childCount < minChildCount)
{
minChildCount = parent.childCount;
minParentIndex = index;
}
index++;
}
return trans.GetParents().SelectIndexOrDefault(minParentIndex - backStep);
}
/// <summary>
/// 获取一个变换节点下所有的子成员
/// </summary>
/// <param name="trans"></param>
/// <param name="recursion">递归深度,0表示仅在第一子集中寻找,1表示在包含下一级在内的所有成员中寻找</param>
/// <returns></returns>
public static IEnumerable<Transform> GetChildren(this Transform trans)
{
#if UNITY_EDITOR
if(trans == null)
throw new Exception("在准备获取所有子成员时,节点为空");
#endif
for(int i = 0; i < trans.childCount; i++)
{
yield return trans.GetChild(i);
}
}
/// <summary>
/// 递归获取一个变换节点下所有的子成员
/// </summary>
/// <param name="trans"></param>
/// <param name="recursion">递归深度,1表示仅在第一子集中寻找,2表示在包含下一级在内的所有成员中寻找</param>
/// <returns></returns>
public static IEnumerable<Transform> GetChildrenRecursion(this Transform trans, int recursion = 1)
{
int newdepth = recursion - 1;
foreach(var child in trans.GetChildren())
{
if(newdepth > 0)
foreach(var item in child.GetChildrenRecursion(newdepth))
yield return item;
yield return child;
}
}
/// <summary>
/// 在所有子成员中深度优先找到第一个组件;
/// 注意这只会在子项中查找。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="trans"></param>
/// <param name="recursion">遍历深度,1表示仅在子集中寻找,2表示在子集中寻找,如果找不到的将在子集的子集中寻找,以此类推</param>
/// <returns></returns>
public static IEnumerable<T> GetComponentsInRecursionChildren<T>(this Transform trans, int recursion = 1)
where T : Component
{
int newRecursion = recursion - 1;
foreach(var item in trans.GetChildren())
{
var comp = item.GetComponent<T>();
if(comp == null && newRecursion > 0)
comp = item.GetComponentInRecursionChildren<T>(newRecursion);
yield return comp;
}
}
/// <summary>
/// 按深度优先寻找一个组件;
/// 注意这只会在子项中查找。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="trans"></param>
/// <param name="depth">遍历深度,0表示仅在子集中寻找,1表示在子集中寻找,如果找不到的将在子集的子集中寻找,以此类推</param>
/// <returns></returns>
public static T GetComponentInRecursionChildren<T>(this Transform trans, int depth = 1)
where T : Component
{
T result;
int newDepth = depth - 1;
#if true // 如果不知道这里在找什么的可以打开调试看看
foreach(var item in trans.GetChildren())
{
result = item.GetComponent<T>();
if(result == null && newDepth > 0)
result = item.GetComponentInRecursionChildren<T>(newDepth);
if(result != null)
return result;
}
#else
string info = $"{depth}. 开始在{trans.name}中寻找\r\n";
foreach(var item in trans.GetChildren())
{
info += $"{depth}. > 正在{item.name}中寻找\r\n";
result = item.GetComponent<T>();
info += $"{depth}. 当前节点{(result == null ? "不包含组件":"包含组件")}\r\n";
if(result == null && newDepth >= 0)
{
info += $"{depth}. 前往深层寻找 > \r\n";
result = item.GetRecursionComponent<T>(newDepth);
info += $"{depth}. 深层查找返回 < \r\n";
}
if(result != null)
{
info += $"{depth}. 已找到结果:{result.name} \r\n";
Debug.Log(info);
return result;
}
info += $"{depth}. 没有找到任何东西 \r\n";
}
Debug.Log(info + "没有找到,空结束");
#endif
return null;
}
/// <summary>
/// 无论如何都要获取一个组件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetComponentAnyway<T>(this GameObject obj)
where T : Component
{
var component = obj.GetComponent<T>();
if(component is null)
component = obj.AddComponent<T>();
return component;
}
/// <summary>
/// 无论如何都要获取一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T GetObjectAnyway<T>(this T obj)
where T : new()
{
if(obj is null)
obj = new T();
return obj;
}
#endregion
#region 2023/10 过时
/// <summary>
/// 在所有子成员中深度优先找到第一个组件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="trans"></param>
/// <param name="recursion">遍历深度,0表示仅在此处寻找,1表示在包含下一级在内的所有成员中寻找</param>
/// <returns></returns>
[Obsolete("命名不符合规则,将使用GetComponentsInRecursionChildren替换")]
public static IEnumerable<T> GetChildrenRecursionComponents<T>(this Transform trans, int recursion = 1)
where T : Component
{
int newRecursion = recursion - 1;
foreach(var item in trans.GetChildren())
{
var comp = item.GetComponent<T>();
if(comp == null && newRecursion > 0)
comp = item.GetChildrenRecursionComponent<T>(newRecursion);
yield return comp;
}
}
/// <summary>
/// 按深度优先寻找一个组件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="trans"></param>
/// <param name="depth">遍历深度,0表示仅在第一子集中寻找,1表示在包含下一级在内的所有成员中寻找</param>
/// <returns></returns>
[Obsolete("命名不符合规则,将使用GetComponentsInRecursionChildren替换")]
public static T GetChildrenRecursionComponent<T>(this Transform trans, int depth = 1)
where T : Component
{
T result;
int newDepth = depth - 1;
foreach(var item in trans.GetChildren())
{
result = item.GetComponent<T>();
if(result == null && newDepth > 0)
result = item.GetChildrenRecursionComponent<T>(newDepth);
if(result != null)
return result;
}
return null;
}
#endregion
}
}