130 lines
4.3 KiB
C#
130 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
|
|
namespace Framework.Core
|
|
{
|
|
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
|
public class FindComponentAttribute : Attribute
|
|
{
|
|
public readonly string goName;
|
|
public readonly bool getChild;
|
|
|
|
/// <summary>
|
|
/// 查找游戏物体组件的特性
|
|
/// </summary>
|
|
/// <param name="goName">游戏物体名字</param>
|
|
/// <param name="getChild">
|
|
/// true => 查找对应名字对象的下一级子物体 通常名字为父物体名字 类型为子物体
|
|
/// false => 查找对应名字的对象 通常会将类型和名字对应</param>
|
|
public FindComponentAttribute(string goName = null, bool getChild = true)
|
|
{
|
|
this.goName = goName;
|
|
this.getChild = getChild;
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
|
public class FindComponentsInChildrenAttribute : Attribute
|
|
{
|
|
/// 空类
|
|
/// 直接获取下层所有组件
|
|
}
|
|
|
|
public static class UnityTool
|
|
{
|
|
/// <summary>
|
|
/// 查找所有带标记的组件
|
|
/// 与FindComponent特性配合使用
|
|
/// </summary>
|
|
public static void FindComponents(this Component mono)
|
|
{
|
|
Dictionary<Type, Component[]> dic = new();
|
|
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
|
|
foreach (var field in mono.GetType().GetFields(flags))
|
|
{
|
|
Attribute attribute = GetFindCompAttribute(field);
|
|
if (attribute == null) continue;
|
|
|
|
Type type = field.FieldType;
|
|
var components = GetComponentsByType(mono, type, dic);
|
|
|
|
switch (attribute)
|
|
{
|
|
case FindComponentAttribute componentAttribute:
|
|
HandleFindComponent(mono, field, components, componentAttribute);
|
|
break;
|
|
case FindComponentsInChildrenAttribute:
|
|
HandleFindComponentsInChildren(mono, field, components);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static Attribute GetFindCompAttribute(FieldInfo field)
|
|
{
|
|
var attr1 = field.GetCustomAttribute<FindComponentAttribute>();
|
|
if (attr1 != null)
|
|
{
|
|
return attr1;
|
|
}
|
|
|
|
var attr2 = field.GetCustomAttribute<FindComponentsInChildrenAttribute>();
|
|
return attr2;
|
|
}
|
|
|
|
private static void HandleFindComponent(Component mono, FieldInfo field, Component[] components,
|
|
FindComponentAttribute attribute)
|
|
{
|
|
if (string.IsNullOrEmpty(attribute.goName))
|
|
{
|
|
field.SetValue(mono, components[0]);
|
|
return;
|
|
}
|
|
|
|
if (attribute.getChild)
|
|
{
|
|
foreach (var component in components)
|
|
{
|
|
if (component.transform.parent.name == attribute.goName)
|
|
{
|
|
field.SetValue(mono, component);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var component in components)
|
|
{
|
|
if (component.name != attribute.goName) continue;
|
|
field.SetValue(mono, component);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void HandleFindComponentsInChildren(Component mono, FieldInfo field, Component[] components)
|
|
{
|
|
field.SetValue(mono, components);
|
|
}
|
|
|
|
private static Component[] GetComponentsByType(Component mono, Type type, Dictionary<Type, Component[]> dic)
|
|
{
|
|
if (dic.TryGetValue(type, out var components)) return components;
|
|
|
|
components = mono.GetComponentsInChildren(type, true);
|
|
if (components == null || components.Length == 0)
|
|
{
|
|
#if UNITY_EDITOR
|
|
Debug.Log($"无法找到{type}对象");
|
|
#endif
|
|
return null;
|
|
}
|
|
|
|
dic.Add(type, components);
|
|
return components;
|
|
}
|
|
}
|
|
} |