using System; using System.Reflection; using EventWorkClass; using Map; using UnityEngine; namespace Utils { public static class StringUtils { /// /// 尝试从字符串中解析出指定数量的浮点数组件。 /// 这是StringToVector2和StringToVector3的核心辅助方法。 /// /// 要解析的源字符串。 /// 期望的组件数量(例如,Vector2为2,Vector3为3)。 /// 如果解析成功,包含解析出的浮点数;否则为 null。 /// 在解析失败时,用于填充parsedComponents数组的默认值。 /// 如果所有组件都成功解析,则返回 true;否则返回 false。 private static bool TryParseVectorComponents( string source, int expectedComponentCount, out float[] parsedComponents, float defaultComponentValue = 0f) { parsedComponents = new float[expectedComponentCount]; if (string.IsNullOrWhiteSpace(source)) { for (var i = 0; i < expectedComponentCount; i++) { parsedComponents[i] = defaultComponentValue; } return false; } // 移除所有可能存在的括号或方括号 // 采用Replace而不是Regex是因为简单字符替换的性能优势 var cleanedSource = source .Replace("[", "") .Replace("]", "") .Replace("(", "") .Replace(")", ""); // 定义所有可能的分隔符:逗号、空格、分号 // 使用 StringSplitOptions.RemoveEmptyEntries 确保即使有多个分隔符连续出现,也不会创建空字符串项 char[] delimiters = { ',', ' ', ';' }; var componentStrings = cleanedSource.Split( delimiters, System.StringSplitOptions.RemoveEmptyEntries); if (componentStrings.Length < expectedComponentCount) { for (var i = 0; i < expectedComponentCount; i++) { parsedComponents[i] = defaultComponentValue; } return false; } for (var i = 0; i < expectedComponentCount; i++) { // 尝试解析每个组件,并去除前后空格 if (!float.TryParse(componentStrings[i].Trim(), out parsedComponents[i])) { for (var j = 0; j < expectedComponentCount; j++) { parsedComponents[j] = defaultComponentValue; } return false; } } return true; // 所有组件都成功解析 } /// /// 将字符串转换为 Unity 的 Vector2。 /// 支持格式如 "1,2", "[1 2]", "(1;2)",并能处理空格。 /// /// 要转换的字符串。 /// 转换失败时返回的默认 Vector2 值。 /// 转换后的 Vector2 值或默认值。 public static Vector2 StringToVector2(string str, Vector2 defaultValue = default) { if (defaultValue == default) { defaultValue = Vector2.zero; // 如果未指定,则使用 Vector2.zero 作为默认值 } if (TryParseVectorComponents(str, 2, out var components)) { return new Vector2(components[0], components[1]); } Debug.LogWarning($"将字符串 \"{str}\" 解析为 Vector2 失败。返回默认值 {defaultValue}。"); return defaultValue; } /// /// 将字符串转换为 Unity 的 Vector3。 /// 支持格式如 "1,2,3", "[1 2 3]", "(1;2;3)",并能处理空格。 /// /// 要转换的字符串。 /// 转换失败时返回的默认 Vector3 值。 /// 转换后的 Vector3 值或默认值。 public static Vector3 StringToVector3(string str, Vector3 defaultValue = default) { if (defaultValue == default) { defaultValue = Vector3.zero; // 如果未指定,则使用 Vector3.zero 作为默认值 } if (TryParseVectorComponents(str, 3, out var components)) { return new Vector3(components[0], components[1], components[2]); } Debug.LogWarning($"将字符串 \"{str}\" 解析为 Vector3 失败。返回默认值 {defaultValue}。"); return defaultValue; } /// /// 尝试从字符串中解析出指定数量的整数组件。 /// 这是StringToVector3Int的核心辅助方法。 /// /// 要解析的源字符串。 /// 期望的组件数量(例如,Vector3Int为3)。 /// 如果解析成功,包含解析出的整数;否则为 null。 /// 在解析失败时,用于填充parsedComponents数组的默认值。 /// 如果所有组件都成功解析,则返回 true;否则返回 false。 private static bool TryParseVectorIntComponents( string source, int expectedComponentCount, out int[] parsedComponents, int defaultComponentValue = 0) { parsedComponents = new int[expectedComponentCount]; if (string.IsNullOrWhiteSpace(source)) { for (var i = 0; i < expectedComponentCount; i++) { parsedComponents[i] = defaultComponentValue; } return false; } // 移除所有可能存在的括号或方括号 var cleanedSource = source .Replace("[", "") .Replace("]", "") .Replace("(", "") .Replace(")", ""); // 定义所有可能的分隔符:逗号、空格、分号 char[] delimiters = { ',', ' ', ';' }; var componentStrings = cleanedSource.Split( delimiters, System.StringSplitOptions.RemoveEmptyEntries); if (componentStrings.Length < expectedComponentCount) { for (var i = 0; i < expectedComponentCount; i++) { parsedComponents[i] = defaultComponentValue; } return false; } for (var i = 0; i < expectedComponentCount; i++) { // 尝试解析每个组件,并去除前后空格 if (!int.TryParse(componentStrings[i].Trim(), out parsedComponents[i])) { for (var j = 0; j < expectedComponentCount; j++) { parsedComponents[j] = defaultComponentValue; } return false; } } return true; // 所有组件都成功解析 } /// /// 将字符串转换为 Unity 的 Vector3Int。 /// 支持格式如 "1,2,3", "[1 2 3]", "(1;2;3)",并能处理空格。 /// /// 要转换的字符串。 /// 转换失败时返回的默认 Vector3Int 值。 /// 转换后的 Vector3Int 值或默认值。 public static Vector3Int StringToVector3Int(string str, Vector3Int defaultValue = default) { if (defaultValue == default) { defaultValue = Vector3Int.zero; // 如果未指定,则使用 Vector3Int.zero 作为默认值 } if (TryParseVectorIntComponents(str, 3, out var components)) { return new Vector3Int(components[0], components[1], components[2]); } Debug.LogWarning($"将字符串 \"{str}\" 解析为 Vector3Int 失败。返回默认值 {defaultValue}。"); return defaultValue; } /// /// 根据类名字符串创建并返回一个继承自 MapGeneratorWorkClassBase 的实例。 /// /// 不含命名空间的类名。 /// 对应的 MapGeneratorWorkClassBase 实例,如果找不到或类型不匹配则返回 null。 public static MapGeneratorWorkClassBase CreateMapGeneratorInstance(string className) { // 定义优先查找的命名空间 const string preferredNamespace = "Map"; Type foundType = null; // 第一遍:优先在指定的命名空间下查找 foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var fullClassNameInPreferredNamespace = preferredNamespace + "." + className; var type = assembly.GetType(fullClassNameInPreferredNamespace); if (type != null) { foundType = type; break; // 找到后立即退出循环,因为我们找到了优先的类型 } } // 如果在优先命名空间中没有找到,则进行第二遍:在所有命名空间中查找(不指定命名空间,即只用className) if (foundType == null) { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var type = assembly.GetType(className); if (type != null) { // 如果找到多个同名的类型(在不同命名空间,但都不在preferredNamespace), // 这里的处理是取第一个找到的。如果需要更复杂的选择逻辑,例如按顺序优先级, // 则需要收集所有可能类型并进行筛选。 // 但对于通常的应用,如果className本身是不带命名空间的,这通常意味着它在全局作用域 // 或者我们期望它在一个特定的命名空间(如preferredNamespace)中。 foundType = type; // 注意:这里没有break;的话,如果不同程序集有同名类会继续查找并覆盖foundType。 // 如果你期望找到第一个就返回,可以加上break; // 如果你期望找到一个满足条件的就返回,那么把后续的检查放到这里。 // 为了简化,我们只在这里找到一个可用的Type,然后统一在后面检查。 break; // 找到了一个,先用这个。 } } } // 对找到的类型进行有效性检查和实例创建 if (foundType != null) { // 检查类型是否: // 1. 是 MapGeneratorWorkClassBase 的子类或本身就是 MapGeneratorWorkClassBase // 2. 不是抽象类 // 3. 有一个无参构造函数 if (typeof(MapGeneratorWorkClassBase).IsAssignableFrom(foundType) && !foundType.IsAbstract && foundType.GetConstructor(Type.EmptyTypes) != null) // 检查是否有无参构造函数 { try { // 使用 Activator.CreateInstance 创建实例 return (MapGeneratorWorkClassBase)Activator.CreateInstance(foundType); } catch (Exception ex) { Debug.LogError($"Error creating instance of {foundType.FullName}: {ex.Message}"); return null; } } var foundTypeName = foundType.FullName; Debug.LogError($"Type '{foundTypeName}' found but does not meet criteria:" + $" IsAssignableFrom({nameof(MapGeneratorWorkClassBase)}): {typeof(MapGeneratorWorkClassBase).IsAssignableFrom(foundType)}," + $" IsAbstract: {foundType.IsAbstract}," + $" HasParameterlessConstructor: {foundType.GetConstructor(Type.EmptyTypes) != null}"); return null; // 类型不满足条件 } Debug.LogError( $"Type '{className}' not found in preferred namespace '{preferredNamespace}' or any loaded assembly."); return null; // 类型未找到 } /// /// 根据类名从指定命名空间和程序集下获取并实例化一个 的子类。 /// /// 要实例化的类的短名称(不包含命名空间)。 /// 目标类所在的完整命名空间。 /// 要搜索的程序集。如果为 null,将搜索 所在的程序集。 /// 实例化后的 对象,如果找不到或不符合条件则返回 null。 public static EventWorkClassBase GetAndInstantiateEventWorker( string className, string targetNamespace = "EventWorkClass", // 默认命名空间 Assembly assemblyToSearch = null) // 默认程序集 { // 1. 确定要搜索的程序集。 if (assemblyToSearch == null) { // 默认从 EventWorkClassBase 所在的程序集查找,通常其实现类也位于此程序集。 assemblyToSearch = typeof(EventWorkClassBase).Assembly; } // 2. 构造完整的类型名称。 var fullTypeName = $"{targetNamespace}.{className}"; Type targetType = null; // 3. 尝试直接从程序集获取类型。 targetType = assemblyToSearch.GetType(fullTypeName); // 4. 进行类型检查。 if (targetType == null) { Debug.LogError($"错误:在程序集 '{assemblyToSearch.FullName}' 的命名空间 '{targetNamespace}' 中未找到类 '{className}'。"); return null; } // 检查是否是 EventWorkClassBase 的子类。 if (!typeof(EventWorkClassBase).IsAssignableFrom(targetType)) { Debug.LogError($"错误:类 '{fullTypeName}' 不是 '{typeof(EventWorkClassBase).FullName}' 的子类。"); return null; } // 检查是否可以实例化(非抽象类,非接口)。 if (targetType.IsAbstract || targetType.IsInterface) { Debug.LogError($"错误:类 '{fullTypeName}' 是抽象类或接口,不能直接实例化。"); return null; } // 5. 实例化对象。 try { // 使用 Activator.CreateInstance 实例化对象。它默认调用无参公共构造函数。 var instance = Activator.CreateInstance(targetType); return instance as EventWorkClassBase; } catch (MissingMethodException ex) { Debug.LogError($"错误:类 '{fullTypeName}' 没有公共的无参构造函数。详细信息: {ex.Message}"); return null; } catch (Exception ex) { Debug.LogError($"实例化类 '{fullTypeName}' 时发生未知错误。详细信息: {ex.Message}"); return null; } } } }