using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; public static class ReflectionHelper { private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; // --- 设置值 (支持 object) --- public static void SetDeepValue(object target, string path, object newValue) { if (target == null || string.IsNullOrEmpty(path)) return; string[] parts = path.Split('.'); SetDeepValueRecursive(target, parts, 0, newValue); } private static void SetDeepValueRecursive(object currentObj, string[] pathParts, int index, object newValue) { string memberName = pathParts[index]; Type type = currentObj.GetType(); FieldInfo field = type.GetField(memberName, Flags); PropertyInfo prop = type.GetProperty(memberName, Flags); if (field == null && prop == null) { // Debug.LogWarning($"找不到成员: {memberName}"); // 可选:调试用 return; } bool isLast = index == pathParts.Length - 1; if (isLast) { // 到达终点:直接设置值 // 注意:这里可能需要处理类型转换,取决于你的 newValue 类型是否严格匹配 try { if (field != null) field.SetValue(currentObj, newValue); else if (prop != null && prop.CanWrite) prop.SetValue(currentObj, newValue); } catch (Exception e) { Debug.LogError($"设置值失败 {memberName}: {e.Message}"); } } else { // 中间节点 object nextObj = field != null ? field.GetValue(currentObj) : prop.GetValue(currentObj); if (nextObj == null) return; SetDeepValueRecursive(nextObj, pathParts, index + 1, newValue); // Struct 回写逻辑 (关键) if (nextObj.GetType().IsValueType) { if (field != null) field.SetValue(currentObj, nextObj); else if (prop != null && prop.CanWrite) prop.SetValue(currentObj, nextObj); } } } // --- 获取值 (支持 object) --- public static object GetDeepValue(object target, string path) { object current = target; foreach (string part in path.Split('.')) { if (current == null) return null; Type type = current.GetType(); FieldInfo field = type.GetField(part, Flags); if (field != null) { current = field.GetValue(current); continue; } PropertyInfo prop = type.GetProperty(part, Flags); if (prop != null) { current = prop.GetValue(current); continue; } return null; // 路径中断 } return current; } /// /// 遍历对象的所有字段和属性(递归地),查找值与目标值匹配的参数路径。 /// /// 要搜索的对象实例。 /// 要匹配的目标值。 /// 递归搜索的最大深度,防止无限循环。 /// 返回匹配参数的完整路径列表 (例如: "position.x")。 public static List FindParametersByValue(object target, object targetValue, int maxDepth = 10) { if (target == null || targetValue == null) return new List(); // 用于存储找到的路径 var results = new List(); // 用于防止循环引用(比如类 A 内部引用了类 B,类 B 内部又引用了类 A) var visited = new HashSet(); // 启动递归搜索 FindRecursive(target, targetValue, "", 0, results, visited, maxDepth); return results; } private static void FindRecursive( object currentObject, object targetValue, string currentPath, int depth, List results, HashSet visited, int maxDepth) { if (currentObject == null || depth >= maxDepth) return; // 避免无限循环和重复搜索 // 对于值类型 (Struct) 不需要加入 visited,因为它们是副本 if (!currentObject.GetType().IsValueType) { // 如果对象已经被搜索过,则跳过 if (visited.Contains(currentObject)) return; visited.Add(currentObject); } Type currentType = currentObject.GetType(); // 1. 遍历 Field 字段 foreach (var field in currentType.GetFields(Flags)) { // 跳过内部字段,如编译器生成的 backing fields if (field.IsDefined(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), false)) continue; object value = field.GetValue(currentObject); string newPath = string.IsNullOrEmpty(currentPath) ? field.Name : $"{currentPath}.{field.Name}"; CheckAndRecurse(field.FieldType, value, targetValue, newPath, depth, results, visited, maxDepth); } // 2. 遍历 Property 属性 foreach (var prop in currentType.GetProperties(Flags).Where(p => p.CanRead)) { // 跳过索引器 if (prop.GetIndexParameters().Length > 0) continue; object value = prop.GetValue(currentObject); string newPath = string.IsNullOrEmpty(currentPath) ? prop.Name : $"{currentPath}.{prop.Name}"; CheckAndRecurse(prop.PropertyType, value, targetValue, newPath, depth, results, visited, maxDepth); } } /// /// 检查当前值是否匹配,如果不是基础类型则继续递归 /// private static void CheckAndRecurse( Type valueType, object value, object targetValue, string newPath, int depth, List results, HashSet visited, int maxDepth) { if (value == null) return; // 【值匹配检查】 if (value.Equals(targetValue)) { results.Add(newPath); return; } // 【递归检查】 // 只有当值是一个复杂类型(Class 或 Struct)时才需要递归 // 排除字符串和集合(List, Array等,如果你需要搜索集合内部,逻辑会更复杂) if (valueType.IsClass || valueType.IsValueType && !valueType.IsPrimitive) { // 排除 String (虽然是 Class,但我们视其为基础值) if (valueType == typeof(string)) return; // 排除集合(如果需要支持 List 的内部搜索,你需要在这里添加处理逻辑) if (valueType.IsArray || valueType.IsGenericType && valueType.GetInterfaces().Any(i => i == typeof(System.Collections.IEnumerable))) return; // 递归进入下一层 FindRecursive(value, targetValue, newPath, depth + 1, results, visited, maxDepth); } } } public class FastReflection { // 定义一个节点,用来缓存每一层的 Field 或 Property 信息 private class MemberNode { public FieldInfo Field; public PropertyInfo Property; public bool IsField => Field != null; public MemberNode(MemberInfo info) { if (info is FieldInfo f) Field = f; else if (info is PropertyInfo p) Property = p; } // 快速获取值 public object GetValue(object target) { return IsField ? Field.GetValue(target) : Property.GetValue(target); } // 快速设置值 public void SetValue(object target, object value) { if (IsField) Field.SetValue(target, value); else if (Property != null && Property.CanWrite) Property.SetValue(target, value); } // 判断这一层是否是 Struct (值类型),如果是,修改后需要回写 public bool IsStructType() { return IsField ? Field.FieldType.IsValueType : Property.PropertyType.IsValueType; } } // 访问器链条 private readonly List _nodes = new List(); private bool _isValid = false; /// /// 构造函数:初始化时进行昂贵的解析操作(只做一次) /// public FastReflection(object rootTarget, string path) { if (rootTarget == null || string.IsNullOrEmpty(path)) return; Type currentType = rootTarget.GetType(); string[] parts = path.Split('.'); BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; foreach (var part in parts) { // 查找字段或属性 FieldInfo field = currentType.GetField(part, flags); PropertyInfo prop = currentType.GetProperty(part, flags); if (field == null && prop == null) { Debug.LogError($"[FastReflection] 路径中断: 找不到成员 '{part}' 在类型 '{currentType.Name}' 中"); return; } // 创建节点并添加到链条 MemberNode node = new MemberNode(field ?? (MemberInfo)prop); _nodes.Add(node); // 更新 currentType 为下一层的类型 currentType = field != null ? field.FieldType : prop.PropertyType; } _isValid = true; } /// /// 获取值(运行时极快) /// public float GetValue(object rootTarget) { if (!_isValid) return 0f; object current = rootTarget; for (int i = 0; i < _nodes.Count; i++) { current = _nodes[i].GetValue(current); if (current == null) return 0f; } return (float)current; // 假设最后一定是 float } /// /// 设置值(运行时极快,自动处理 Struct 回写) /// public void SetValue(object rootTarget, float newValue) { if (!_isValid) return; // 开始递归处理回写 SetRecursive(rootTarget, 0, newValue); } // 递归函数:处理“获取-修改-回写”逻辑 private void SetRecursive(object currentObj, int index, float finalValue) { MemberNode node = _nodes[index]; // 1. 如果是链条的最后一个节点(即那个 float 变量) if (index == _nodes.Count - 1) { node.SetValue(currentObj, finalValue); return; } // 2. 如果是中间节点,先获取下一层对象 object nextObj = node.GetValue(currentObj); if (nextObj == null) return; // 3. 递归进入下一层 SetRecursive(nextObj, index + 1, finalValue); // 4. 【关键】回写阶段 // 如果 nextObj 是 Struct(值类型),比如 Vector3, // 我们刚才在递归里修改了 nextObj 的副本,现在必须把它赋值回 currentObj if (node.IsStructType()) { node.SetValue(currentObj, nextObj); } } }