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
2023-10-29 17:56:31 +08:00

266 lines
7.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
{
for(int i = 0; i < trans.childCount; i++)
{
yield return trans.GetChild(i);
}
}
/// <summary>
/// 在所有子成员中深度优先找到第一个组件;
/// 注意这只会在子项中查找。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="trans"></param>
/// <param name="recursion">遍历深度0表示仅在子集中寻找1表示在子集中寻找如果找不到的将在子集的子集中寻找以此类推</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
}
}