mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 11:27:14 +08:00
(client) feat:健康给予,路径优化,结算界面,商店界面 (#60)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/60
This commit is contained in:
@@ -1,54 +1,50 @@
|
||||
using System;
|
||||
using Data;
|
||||
using Managers;
|
||||
using Prefab;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
public class GameObjectCreate:Singleton<GameObjectCreate>
|
||||
public class AnimationUtils : Singleton<AnimationUtils>
|
||||
{
|
||||
private static SpriteAnimator _animatorPrefab;
|
||||
|
||||
private static ImagePrefab _imagePrefab;
|
||||
private static ProgressBarPrefab _progressBarPrefab;
|
||||
|
||||
public static SpriteAnimator AnimatorPrefab
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_animatorPrefab)
|
||||
{
|
||||
_animatorPrefab=Resources.Load<SpriteAnimator>("Prefab/ControlUI/Animation");
|
||||
}
|
||||
if (!_animatorPrefab) _animatorPrefab = Resources.Load<SpriteAnimator>("Prefab/ControlUI/Animation");
|
||||
return _animatorPrefab;
|
||||
}
|
||||
}
|
||||
|
||||
private static ImagePrefab _imagePrefab;
|
||||
public static ImagePrefab ImagePrefab
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_imagePrefab)
|
||||
{
|
||||
_imagePrefab=Resources.Load<ImagePrefab>("Prefab/ControlUI/Image");
|
||||
}
|
||||
if (!_imagePrefab) _imagePrefab = Resources.Load<ImagePrefab>("Prefab/ControlUI/Image");
|
||||
return _imagePrefab;
|
||||
}
|
||||
}
|
||||
private static ProgressBarPrefab _progressBarPrefab;
|
||||
|
||||
public static ProgressBarPrefab ProgressBarPrefab
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_progressBarPrefab)
|
||||
{
|
||||
_progressBarPrefab=Resources.Load<ProgressBarPrefab>("Prefab/ControlUI/ProgressBar");
|
||||
}
|
||||
_progressBarPrefab = Resources.Load<ProgressBarPrefab>("Prefab/ControlUI/ProgressBar");
|
||||
return _progressBarPrefab;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 递归初始化单个绘图节点及其子节点,具有更强的健壮性和错误处理。
|
||||
/// 递归初始化单个绘图节点及其子节点,具有更强的健壮性和错误处理。
|
||||
/// </summary>
|
||||
/// <param name="drawNode">绘图节点定义。</param>
|
||||
/// <param name="parent">父节点对象。</param>
|
||||
@@ -86,15 +82,14 @@ namespace Utils
|
||||
Debug.LogError($"InitBodyPart: imagePrefab未设置 (节点名: {drawNode.nodeName})");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (drawNode.textures != null)
|
||||
{
|
||||
var texture =
|
||||
Managers.PackagesImageManager.Instance.GetSprite(drawNode.textures[0]);
|
||||
PackagesImageManager.Instance.GetSprite(drawNode.textures[0]);
|
||||
if (!texture)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"InitBodyPart: 无法获取纹理 (节点名: {drawNode.nodeName}, 纹理ID: {drawNode.textures[0]})");
|
||||
}
|
||||
|
||||
var imagePrefabCom = Object.Instantiate(ImagePrefab, parent.transform);
|
||||
if (imagePrefabCom)
|
||||
@@ -116,7 +111,7 @@ namespace Utils
|
||||
Debug.LogError($"InitBodyPart: animatorPrefab未设置 (节点名: {drawNode.nodeName})");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var animator = Object.Instantiate(AnimatorPrefab, parent.transform);
|
||||
if (!animator)
|
||||
{
|
||||
@@ -128,8 +123,8 @@ namespace Utils
|
||||
if (drawNode.textures != null)
|
||||
{
|
||||
var animatedSprites =
|
||||
Managers.PackagesImageManager.Instance.GetSprites(drawNode.textures);
|
||||
|
||||
PackagesImageManager.Instance.GetSprites(drawNode.textures);
|
||||
|
||||
if (animatedSprites.Length > 0)
|
||||
{
|
||||
animator.SetSprites(animatedSprites);
|
||||
@@ -146,12 +141,11 @@ namespace Utils
|
||||
|
||||
// 设置节点属性
|
||||
if (!nodeObject) return nodeObject;
|
||||
nodeObject.transform.localPosition = drawNode.position;
|
||||
nodeObject.transform.localPosition = StringUtils.StringToVector2(drawNode.position);
|
||||
nodeObject.name = drawNode.nodeName ?? "UnnamedNode";
|
||||
// 递归初始化子节点
|
||||
if (drawNode.nodes == null) return nodeObject;
|
||||
foreach (var child in drawNode.nodes)
|
||||
{
|
||||
try
|
||||
{
|
||||
InitBodyPart(child, nodeObject);
|
||||
@@ -160,7 +154,6 @@ namespace Utils
|
||||
{
|
||||
Debug.LogError($"InitBodyPart: 初始化子节点失败 (父节点: {drawNode.nodeName}): {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return nodeObject;
|
||||
}
|
||||
@@ -171,24 +164,24 @@ namespace Utils
|
||||
}
|
||||
}
|
||||
|
||||
public static SpriteAnimator SpriteAnimator(Sprite[] sprites,Transform parent)
|
||||
public static SpriteAnimator SpriteAnimator(Sprite[] sprites, Transform parent)
|
||||
{
|
||||
var spriteAnimator = Object.Instantiate(AnimatorPrefab,parent);
|
||||
var spriteAnimator = Object.Instantiate(AnimatorPrefab, parent);
|
||||
spriteAnimator.SetSprites(sprites);
|
||||
spriteAnimator.transform.localPosition=Vector3.zero;
|
||||
spriteAnimator.transform.localPosition = Vector3.zero;
|
||||
return spriteAnimator;
|
||||
}
|
||||
|
||||
public static SpriteAnimator SpriteAnimator(string[] spriteDefNames, Transform parent)
|
||||
{
|
||||
return SpriteAnimator(Managers.PackagesImageManager.Instance.GetSprites(spriteDefNames), parent);
|
||||
return SpriteAnimator(PackagesImageManager.Instance.GetSprites(spriteDefNames), parent);
|
||||
}
|
||||
|
||||
public static ImagePrefab SpriteImage(Sprite sprite, Transform parent)
|
||||
{
|
||||
var spriteImage = Object.Instantiate(ImagePrefab,parent);
|
||||
var spriteImage = Object.Instantiate(ImagePrefab, parent);
|
||||
spriteImage.SetSprite(sprite);
|
||||
spriteImage.transform.localPosition=Vector3.zero;
|
||||
spriteImage.transform.localPosition = Vector3.zero;
|
||||
return spriteImage;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace Utils
|
||||
public static class BehaviorTreeUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// 将行为树定义转换为 AIBase 类型。
|
||||
/// 将行为树定义转换为 AIBase 类型。
|
||||
/// </summary>
|
||||
/// <param name="behaviorTreeDef">行为树定义。</param>
|
||||
/// <returns>转换后的 AIBase 实例。</returns>
|
||||
@@ -20,7 +20,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用反射根据类名创建 AIBase 的具体子类实例。
|
||||
/// 使用反射根据类名创建 AIBase 的具体子类实例。
|
||||
/// </summary>
|
||||
/// <param name="className">类名。</param>
|
||||
/// <returns>创建的 AIBase 子类实例。</returns>
|
||||
@@ -29,14 +29,11 @@ namespace Utils
|
||||
if (string.IsNullOrEmpty(className))
|
||||
throw new ArgumentException("className 不能为空");
|
||||
if (className.Equals("AIBase", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return (BehaviorTreeBase)Activator.CreateInstance(typeof(BehaviorTreeBase));
|
||||
}
|
||||
// 定义可能的命名空间列表
|
||||
var possibleNamespaces = new[] { "AI" };
|
||||
|
||||
foreach (var ns in possibleNamespaces)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取当前程序集
|
||||
@@ -46,16 +43,13 @@ namespace Utils
|
||||
var type = assembly.GetType($"{ns}.{className}");
|
||||
|
||||
if (type != null && typeof(BehaviorTreeBase).IsAssignableFrom(type))
|
||||
{
|
||||
// 如果找到合适的类型,则创建实例并返回
|
||||
return (BehaviorTreeBase)Activator.CreateInstance(type);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略单个命名空间的错误,继续尝试下一个命名空间
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有命名空间都未找到对应的类型,抛出异常
|
||||
throw new InvalidOperationException($"无法找到类型 {className} 或该类型不是 AIBase 的子类");
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Utils
|
||||
public static class MousePosition
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取鼠标的屏幕位置(以像素为单位)。
|
||||
/// 获取鼠标的屏幕位置(以像素为单位)。
|
||||
/// </summary>
|
||||
/// <returns>鼠标的屏幕位置 (Vector2)。</returns>
|
||||
public static Vector2 GetScreenPosition()
|
||||
@@ -14,17 +14,14 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取鼠标的二维世界位置(基于主摄像机的屏幕到世界转换)。
|
||||
/// 获取鼠标的二维世界位置(基于主摄像机的屏幕到世界转换)。
|
||||
/// </summary>
|
||||
/// <param name="camera">用于计算的摄像机,默认为主摄像机。</param>
|
||||
/// <returns>鼠标的二维世界位置 (Vector2)。</returns>
|
||||
public static Vector2 GetWorldPosition(Camera camera = null)
|
||||
{
|
||||
// 如果未指定摄像机,则使用主摄像机
|
||||
if (!camera)
|
||||
{
|
||||
camera = Camera.main;
|
||||
}
|
||||
if (!camera) camera = Camera.main;
|
||||
|
||||
// 获取鼠标屏幕位置
|
||||
var mouseScreenPosition = Input.mousePosition;
|
||||
@@ -37,7 +34,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取鼠标的二维世界位置并进行整数吸附(基于主摄像机的屏幕到世界转换)。
|
||||
/// 获取鼠标的二维世界位置并进行整数吸附(基于主摄像机的屏幕到世界转换)。
|
||||
/// </summary>
|
||||
/// <param name="camera">用于计算的摄像机,默认为主摄像机。</param>
|
||||
/// <returns>吸附后的二维世界位置 (Vector2Int)。</returns>
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化混淆表。
|
||||
/// 初始化混淆表。
|
||||
/// </summary>
|
||||
/// <param name="seed">随机种子。</param>
|
||||
private void Initialize(int seed = 0)
|
||||
@@ -40,7 +40,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新指定种子并初始化混淆表。
|
||||
/// 重新指定种子并初始化混淆表。
|
||||
/// </summary>
|
||||
/// <param name="seed">随机种子。</param>
|
||||
public void Reinitialize(int seed)
|
||||
@@ -49,7 +49,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perlin噪声平滑函数 (6t^5 - 15t^4 + 10t^3)。
|
||||
/// Perlin噪声平滑函数 (6t^5 - 15t^4 + 10t^3)。
|
||||
/// </summary>
|
||||
/// <param name="t">输入值。</param>
|
||||
/// <returns>平滑后的值。</returns>
|
||||
@@ -59,7 +59,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 线性插值。
|
||||
/// 线性插值。
|
||||
/// </summary>
|
||||
/// <param name="t">插值因子 (0-1)。</param>
|
||||
/// <param name="a">起始值。</param>
|
||||
@@ -71,7 +71,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算梯度向量和距离向量的点积。
|
||||
/// 计算梯度向量和距离向量的点积。
|
||||
/// </summary>
|
||||
/// <param name="hash">哈希值,用于决定梯度向量方向。</param>
|
||||
/// <param name="x">X轴距离。</param>
|
||||
@@ -103,8 +103,8 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为给定的(x, y, z)坐标生成3D Perlin噪声。
|
||||
/// 输出值通常在-1到1之间。
|
||||
/// 为给定的(x, y, z)坐标生成3D Perlin噪声。
|
||||
/// 输出值通常在-1到1之间。
|
||||
/// </summary>
|
||||
/// <param name="x">X坐标。</param>
|
||||
/// <param name="y">Y坐标,默认为0。</param>
|
||||
@@ -153,4 +153,4 @@ namespace Utils
|
||||
return Lerp(w, y0, y1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace Utils
|
||||
public static class RotateTool
|
||||
{
|
||||
// 旋转对象到指定方向
|
||||
|
||||
|
||||
public static float RotateTransformToDirection(Transform transform, Vector3 targetDirection)
|
||||
{
|
||||
// 确保目标方向不是零向量
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using EventWorkClass;
|
||||
@@ -10,8 +9,8 @@ namespace Utils
|
||||
public static class StringUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// 尝试从字符串中解析出指定数量的浮点数组件。
|
||||
/// 这是StringToVector2和StringToVector3的核心辅助方法。
|
||||
/// 尝试从字符串中解析出指定数量的浮点数组件。
|
||||
/// 这是StringToVector2和StringToVector3的核心辅助方法。
|
||||
/// </summary>
|
||||
/// <param name="source">要解析的源字符串。</param>
|
||||
/// <param name="expectedComponentCount">期望的组件数量(例如,Vector2为2,Vector3为3)。</param>
|
||||
@@ -27,12 +26,10 @@ namespace Utils
|
||||
parsedComponents = new float[expectedComponentCount];
|
||||
if (string.IsNullOrWhiteSpace(source))
|
||||
{
|
||||
for (var i = 0; i < expectedComponentCount; i++)
|
||||
{
|
||||
parsedComponents[i] = defaultComponentValue;
|
||||
}
|
||||
for (var i = 0; i < expectedComponentCount; i++) parsedComponents[i] = defaultComponentValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 移除所有可能存在的括号或方括号
|
||||
// 采用Replace而不是Regex是因为简单字符替换的性能优势
|
||||
var cleanedSource = source
|
||||
@@ -45,75 +42,58 @@ namespace Utils
|
||||
char[] delimiters = { ',', ' ', ';' };
|
||||
var componentStrings = cleanedSource.Split(
|
||||
delimiters,
|
||||
System.StringSplitOptions.RemoveEmptyEntries);
|
||||
StringSplitOptions.RemoveEmptyEntries);
|
||||
if (componentStrings.Length < expectedComponentCount)
|
||||
{
|
||||
for (var i = 0; i < expectedComponentCount; i++)
|
||||
{
|
||||
parsedComponents[i] = defaultComponentValue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
for (var j = 0; j < expectedComponentCount; j++) parsedComponents[j] = defaultComponentValue;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // 所有组件都成功解析
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字符串转换为 Unity 的 Vector2。
|
||||
/// 支持格式如 "1,2", "[1 2]", "(1;2)",并能处理空格。
|
||||
/// 将字符串转换为 Unity 的 Vector2。
|
||||
/// 支持格式如 "1,2", "[1 2]", "(1;2)",并能处理空格。
|
||||
/// </summary>
|
||||
/// <param name="str">要转换的字符串。</param>
|
||||
/// <param name="defaultValue">转换失败时返回的默认 Vector2 值。</param>
|
||||
/// <returns>转换后的 Vector2 值或默认值。</returns>
|
||||
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]);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字符串转换为 Unity 的 Vector3。
|
||||
/// 支持格式如 "1,2,3", "[1 2 3]", "(1;2;3)",并能处理空格。
|
||||
/// 将字符串转换为 Unity 的 Vector3。
|
||||
/// 支持格式如 "1,2,3", "[1 2 3]", "(1;2;3)",并能处理空格。
|
||||
/// </summary>
|
||||
/// <param name="str">要转换的字符串。</param>
|
||||
/// <param name="defaultValue">转换失败时返回的默认 Vector3 值。</param>
|
||||
/// <returns>转换后的 Vector3 值或默认值。</returns>
|
||||
public static Vector3 StringToVector3(string str, Vector3 defaultValue = default)
|
||||
{
|
||||
if (defaultValue == default)
|
||||
{
|
||||
defaultValue = Vector3.zero; // 如果未指定,则使用 Vector3.zero 作为默认值
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试从字符串中解析出指定数量的整数组件。
|
||||
/// 这是StringToVector3Int的核心辅助方法。
|
||||
/// 尝试从字符串中解析出指定数量的整数组件。
|
||||
/// 这是StringToVector3Int的核心辅助方法。
|
||||
/// </summary>
|
||||
/// <param name="source">要解析的源字符串。</param>
|
||||
/// <param name="expectedComponentCount">期望的组件数量(例如,Vector3Int为3)。</param>
|
||||
@@ -129,12 +109,10 @@ namespace Utils
|
||||
parsedComponents = new int[expectedComponentCount];
|
||||
if (string.IsNullOrWhiteSpace(source))
|
||||
{
|
||||
for (var i = 0; i < expectedComponentCount; i++)
|
||||
{
|
||||
parsedComponents[i] = defaultComponentValue;
|
||||
}
|
||||
for (var i = 0; i < expectedComponentCount; i++) parsedComponents[i] = defaultComponentValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 移除所有可能存在的括号或方括号
|
||||
var cleanedSource = source
|
||||
.Replace("[", "")
|
||||
@@ -145,54 +123,43 @@ namespace Utils
|
||||
char[] delimiters = { ',', ' ', ';' };
|
||||
var componentStrings = cleanedSource.Split(
|
||||
delimiters,
|
||||
System.StringSplitOptions.RemoveEmptyEntries);
|
||||
StringSplitOptions.RemoveEmptyEntries);
|
||||
if (componentStrings.Length < expectedComponentCount)
|
||||
{
|
||||
for (var i = 0; i < expectedComponentCount; i++)
|
||||
{
|
||||
parsedComponents[i] = defaultComponentValue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
for (var j = 0; j < expectedComponentCount; j++) parsedComponents[j] = defaultComponentValue;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // 所有组件都成功解析
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字符串转换为 Unity 的 Vector3Int。
|
||||
/// 支持格式如 "1,2,3", "[1 2 3]", "(1;2;3)",并能处理空格。
|
||||
/// 将字符串转换为 Unity 的 Vector3Int。
|
||||
/// 支持格式如 "1,2,3", "[1 2 3]", "(1;2;3)",并能处理空格。
|
||||
/// </summary>
|
||||
/// <param name="str">要转换的字符串。</param>
|
||||
/// <param name="defaultValue">转换失败时返回的默认 Vector3Int 值。</param>
|
||||
/// <returns>转换后的 Vector3Int 值或默认值。</returns>
|
||||
public static Vector3Int StringToVector3Int(string str, Vector3Int defaultValue = default)
|
||||
{
|
||||
if (defaultValue == default)
|
||||
{
|
||||
defaultValue = Vector3Int.zero; // 如果未指定,则使用 Vector3Int.zero 作为默认值
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据类名字符串创建并返回一个继承自 MapGeneratorWorkClassBase 的实例。
|
||||
/// 根据类名字符串创建并返回一个继承自 MapGeneratorWorkClassBase 的实例。
|
||||
/// </summary>
|
||||
/// <param name="className">不含命名空间的类名。</param>
|
||||
/// <returns>对应的 MapGeneratorWorkClassBase 实例,如果找不到或类型不匹配则返回 null。</returns>
|
||||
@@ -215,7 +182,6 @@ namespace Utils
|
||||
|
||||
// 如果在优先命名空间中没有找到,则进行第二遍:在所有命名空间中查找(不指定命名空间,即只用className)
|
||||
if (foundType == null)
|
||||
{
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var type = assembly.GetType(className);
|
||||
@@ -234,7 +200,6 @@ namespace Utils
|
||||
break; // 找到了一个,先用这个。
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 对找到的类型进行有效性检查和实例创建
|
||||
if (foundType != null)
|
||||
@@ -246,7 +211,6 @@ namespace Utils
|
||||
if (typeof(MapGeneratorWorkClassBase).IsAssignableFrom(foundType) &&
|
||||
!foundType.IsAbstract &&
|
||||
foundType.GetConstructor(Type.EmptyTypes) != null) // 检查是否有无参构造函数
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用 Activator.CreateInstance 创建实例
|
||||
@@ -257,7 +221,6 @@ namespace Utils
|
||||
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:" +
|
||||
@@ -273,12 +236,12 @@ namespace Utils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据类名从指定命名空间和程序集下获取并实例化一个 <see cref="EventWorkClassBase"/> 的子类。
|
||||
/// 根据类名从指定命名空间和程序集下获取并实例化一个 <see cref="EventWorkClassBase" /> 的子类。
|
||||
/// </summary>
|
||||
/// <param name="className">要实例化的类的短名称(不包含命名空间)。</param>
|
||||
/// <param name="targetNamespace">目标类所在的完整命名空间。</param>
|
||||
/// <param name="assemblyToSearch">要搜索的程序集。如果为 null,将搜索 <see cref="EventWorkClassBase"/> 所在的程序集。</param>
|
||||
/// <returns>实例化后的 <see cref="EventWorkClassBase"/> 对象,如果找不到或不符合条件则返回 null。</returns>
|
||||
/// <param name="assemblyToSearch">要搜索的程序集。如果为 null,将搜索 <see cref="EventWorkClassBase" /> 所在的程序集。</param>
|
||||
/// <returns>实例化后的 <see cref="EventWorkClassBase" /> 对象,如果找不到或不符合条件则返回 null。</returns>
|
||||
public static EventWorkClassBase GetAndInstantiateEventWorker(
|
||||
string className,
|
||||
string targetNamespace = "EventWorkClass", // 默认命名空间
|
||||
@@ -286,10 +249,8 @@ namespace Utils
|
||||
{
|
||||
// 1. 确定要搜索的程序集。
|
||||
if (assemblyToSearch == null)
|
||||
{
|
||||
// 默认从 EventWorkClassBase 所在的程序集查找,通常其实现类也位于此程序集。
|
||||
assemblyToSearch = typeof(EventWorkClassBase).Assembly;
|
||||
}
|
||||
|
||||
// 2. 构造完整的类型名称。
|
||||
var fullTypeName = $"{targetNamespace}.{className}";
|
||||
@@ -338,4 +299,4 @@ namespace Utils
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user