(client) feat:添加临时动画组件,添加逃跑逻辑
This commit is contained in:
151
Client/Assets/Scripts/Prefab/TemporaryAnimatorText.cs
Normal file
151
Client/Assets/Scripts/Prefab/TemporaryAnimatorText.cs
Normal file
@ -0,0 +1,151 @@
|
||||
using Base;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Prefab
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 临时动画文本组件,用于在指定时间内逐帧显示一系列文本动画。
|
||||
/// 该组件假设 TemporaryAnimator 实现了 ITickable 接口,因此可以在游戏循环中接收更新。
|
||||
/// </summary>
|
||||
public class TemporaryAnimatorText : TemporaryAnimator
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于显示动画文本的 TMP_Text 组件。
|
||||
/// 允许在编辑器中赋值,以增加灵活性和鲁棒性。
|
||||
/// </summary>
|
||||
[SerializeField] public TMP_Text text;
|
||||
|
||||
/// <summary>
|
||||
/// 当前播放的动画帧索引。
|
||||
/// </summary>
|
||||
private int currentFrameIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 存储所有动画帧文本的字符串数组。每个元素代表一帧动画内容。
|
||||
/// </summary>
|
||||
private string[] animationsKey;
|
||||
|
||||
/// <summary>
|
||||
/// 每帧动画的持续时间(秒)。根据帧率(FPS)计算得出。
|
||||
/// </summary>
|
||||
private float frameDuration;
|
||||
|
||||
/// <summary>
|
||||
/// 用于跟踪当前帧已持续时间的计时器。
|
||||
/// </summary>
|
||||
private float timer;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化动画文本组件。
|
||||
/// </summary>
|
||||
/// <param name="s">包含所有动画帧文本的字符串,多个帧之间用逗号分隔。</param>
|
||||
/// <param name="fps">动画播放的帧率(Frames Per Second)。</param>
|
||||
public void Init(string s, float fps=3)
|
||||
{
|
||||
// 如果文本组件未赋值,尝试在子对象中查找。
|
||||
// 如果仍未找到,则记录错误并提前退出。
|
||||
if (!text)
|
||||
{
|
||||
text = GetComponentInChildren<TMP_Text>();
|
||||
if (!text)
|
||||
{
|
||||
Debug.LogError("TemporaryAnimatorText: 未在子对象中找到或未指定 TMP_Text 组件。动画无法进行。", this);
|
||||
|
||||
return; // 提前退出 Init 方法,避免后续操作使用未初始化的 text
|
||||
}
|
||||
}
|
||||
|
||||
// 处理输入字符串为 null 或空字符串的情况。
|
||||
// 在这种情况下,动画将显示空字符串或停止。
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
Debug.LogWarning("TemporaryAnimatorText: 输入的动画字符串为空或为 null。动画将显示空字符串或停止。", this);
|
||||
animationsKey = new string[] { "" }; // 确保 animationsKey 不为 null 且至少包含一个空字符串元素
|
||||
}
|
||||
else
|
||||
{
|
||||
animationsKey = s.Split(',');
|
||||
// 如果 s.Split(',') 结果为空数组(这种情况极少见,但在某些 Split 重载下可能发生),也应进行处理。
|
||||
if (animationsKey.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("TemporaryAnimatorText: 输入的动画字符串导致动画帧数组为空。动画将显示空字符串或停止。", this);
|
||||
animationsKey = new string[] { "" };
|
||||
}
|
||||
}
|
||||
|
||||
// 检查帧率(FPS)的合法性。FPS 必须是大于 0 的正值。
|
||||
// 如果帧率不合法,则设置为默认值,防止除以零或动画速度异常。
|
||||
if (fps <= 0)
|
||||
{
|
||||
Debug.LogError("TemporaryAnimatorText: FPS 必须是大于 0 的正值。将动画帧持续时间设置为 1 秒。", this);
|
||||
this.frameDuration = 1f; // 默认每帧1秒,实际效果是动画暂停或非常慢
|
||||
}
|
||||
else
|
||||
{
|
||||
this.frameDuration = 1f / fps;
|
||||
}
|
||||
|
||||
// 重新初始化动画时,将当前帧索引重置为第一帧。
|
||||
currentFrameIndex = 0;
|
||||
|
||||
// 在 animationsKey 准备好后,设置初始文本为第一帧的内容。
|
||||
if (text && animationsKey.Length > 0)
|
||||
{
|
||||
text.text = animationsKey[currentFrameIndex];
|
||||
}
|
||||
// 如果动画帧数组为空,但文本组件存在,则清空文本显示。
|
||||
else if (text)
|
||||
{
|
||||
text.text = "";
|
||||
}
|
||||
|
||||
// 重置计时器,从零开始计算新帧的持续时间。
|
||||
timer = 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 每帧更新动画显示。该方法将在游戏循环中被 Clock 调用。
|
||||
/// </summary>
|
||||
public override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
if (!text)
|
||||
{
|
||||
Debug.LogWarning("TemporaryAnimatorText: 在 Tick 方法执行期间 TMP_Text 组件为 null。正在从 Clock 中移除。", this);
|
||||
return; // 无法执行动画,直接返回
|
||||
}
|
||||
|
||||
// 检查动画帧数组是否已初始化或为空。
|
||||
// 如果没有动画帧,则无需更新,直接返回。
|
||||
if (animationsKey == null || animationsKey.Length == 0)
|
||||
{
|
||||
// Debug.LogWarning("TemporaryAnimatorText: 动画键未初始化或为空。跳过 Tick 更新。", this); // 这条日志已被注释掉,避免频繁输出不必要的警告
|
||||
return; // 没有动画帧,直接返回
|
||||
}
|
||||
|
||||
// 增加计时器。
|
||||
timer += Time.deltaTime;
|
||||
|
||||
// 如果当前帧的持续时间已达到或超过预设的帧持续时间,则更新到下一帧。
|
||||
if (!(timer >= frameDuration)) return;
|
||||
|
||||
// 减去一帧的持续时间,以便计算下一帧的剩余时间,或者处理帧率不精确导致的累计误差。
|
||||
timer -= frameDuration;
|
||||
|
||||
// 移动到下一帧。
|
||||
currentFrameIndex += 1;
|
||||
|
||||
// 如果当前帧索引超出动画帧数组的范围,则循环回到第一帧。
|
||||
if (currentFrameIndex >= animationsKey.Length)
|
||||
{
|
||||
currentFrameIndex = 0;
|
||||
}
|
||||
|
||||
// 更新文本组件显示为当前帧的文本内容。
|
||||
text.text = animationsKey[currentFrameIndex];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user