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; /// /// 查找游戏物体组件的特性 /// /// 游戏物体名字 /// /// true => 查找对应名字对象的下一级子物体 通常名字为父物体名字 类型为子物体 /// false => 查找对应名字的对象 通常会将类型和名字对应 public FindComponentAttribute(string goName, bool getChild = true) { this.goName = goName; this.getChild = getChild; } } public static class UnityTool { /// /// 查找所有带标记的组件 /// 与FindComponent特性配合使用 /// public static void FindComponents(this Component mono) { Dictionary dic = null; var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; foreach (var field in mono.GetType().GetFields(flags)) { var attribute = field.GetCustomAttribute(); if (attribute == null) continue; dic ??= new Dictionary(); Type type = field.FieldType; if (!dic.TryGetValue(type, out var components)) { components = mono.GetComponentsInChildren(type, true); if (components == null || components.Length == 0) { #if UNITY_EDITOR Debug.Log($"无法找到{type}对象"); #endif continue; } dic.Add(type, components); } 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; } } } } } }