Files
Gen_Hack-and-Slash-Roguelite/Client/Assets/Scripts/Utils/AnimationUtils.cs

188 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using Data;
using Managers;
using Prefab;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Utils
{
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");
return _animatorPrefab;
}
}
public static ImagePrefab ImagePrefab
{
get
{
if (!_imagePrefab) _imagePrefab = Resources.Load<ImagePrefab>("Prefab/ControlUI/Image");
return _imagePrefab;
}
}
public static ProgressBarPrefab ProgressBarPrefab
{
get
{
if (!_progressBarPrefab)
_progressBarPrefab = Resources.Load<ProgressBarPrefab>("Prefab/ControlUI/ProgressBar");
return _progressBarPrefab;
}
}
/// <summary>
/// 递归初始化单个绘图节点及其子节点,具有更强的健壮性和错误处理。
/// </summary>
/// <param name="drawNode">绘图节点定义。</param>
/// <param name="parent">父节点对象。</param>
/// <returns>创建的GameObject如果失败则返回null</returns>
public static GameObject InitBodyPart(DrawNodeDef drawNode, GameObject parent)
{
try
{
// 参数验证
if (drawNode == null)
{
Debug.LogWarning("InitBodyPart: drawNode参数为null");
return null;
}
if (!parent)
{
Debug.LogWarning($"InitBodyPart: 父节点为null (节点名: {drawNode.nodeName})");
return null;
}
GameObject nodeObject = null;
// 根据纹理数量创建不同类型的节点
switch (drawNode.textures?.Length ?? 0)
{
case 0:
// 无纹理节点
nodeObject = new GameObject(drawNode.nodeName);
nodeObject.transform.SetParent(parent.transform, false);
break;
case 1:
// 单纹理节点
if (!ImagePrefab)
{
Debug.LogError($"InitBodyPart: imagePrefab未设置 (节点名: {drawNode.nodeName})");
return null;
}
if (drawNode.textures != null)
{
var texture =
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)
{
imagePrefabCom.SetSprite(texture);
nodeObject = imagePrefabCom.gameObject;
}
else
{
Debug.LogWarning($"InitBodyPart: 无法获取ImagePrefab组件 (节点名: {drawNode.nodeName})");
}
}
break;
default:
// 多纹理动画节点
if (!AnimatorPrefab)
{
Debug.LogError($"InitBodyPart: animatorPrefab未设置 (节点名: {drawNode.nodeName})");
return null;
}
var animator = Object.Instantiate(AnimatorPrefab, parent.transform);
if (!animator)
{
Debug.LogWarning($"InitBodyPart: 无法获取SpriteAnimator组件 (节点名: {drawNode.nodeName})");
break;
}
animator.SetFPS(drawNode.FPS);
if (drawNode.textures != null)
{
var animatedSprites =
PackagesImageManager.Instance.GetSprites(drawNode.textures);
if (animatedSprites.Length > 0)
{
animator.SetSprites(animatedSprites);
nodeObject = animator.gameObject;
}
else
{
Debug.LogWarning($"InitBodyPart: 没有有效的动画纹理 (节点名: {drawNode.nodeName})");
}
}
break;
}
// 设置节点属性
if (!nodeObject) return nodeObject;
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);
}
catch (Exception ex)
{
Debug.LogError($"InitBodyPart: 初始化子节点失败 (父节点: {drawNode.nodeName}): {ex.Message}");
}
return nodeObject;
}
catch (Exception ex)
{
Debug.LogError($"InitBodyPart: 初始化节点时发生未处理的异常 (节点名: {drawNode?.nodeName}): {ex}");
return null;
}
}
public static SpriteAnimator SpriteAnimator(Sprite[] sprites, Transform parent)
{
var spriteAnimator = Object.Instantiate(AnimatorPrefab, parent);
spriteAnimator.SetSprites(sprites);
spriteAnimator.transform.localPosition = Vector3.zero;
return spriteAnimator;
}
public static SpriteAnimator SpriteAnimator(string[] spriteDefNames, Transform parent)
{
return SpriteAnimator(PackagesImageManager.Instance.GetSprites(spriteDefNames), parent);
}
public static ImagePrefab SpriteImage(Sprite sprite, Transform parent)
{
var spriteImage = Object.Instantiate(ImagePrefab, parent);
spriteImage.SetSprite(sprite);
spriteImage.transform.localPosition = Vector3.zero;
return spriteImage;
}
}
}