Files
Gen_Hack-and-Slash-Roguelite/Client/Assets/Scripts/Prefab/BaseAnimator.cs

139 lines
4.5 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.

// Base/BaseAnimator.cs
using System;
using UnityEngine;
using Base; // 假设ITick接口在这个命名空间
namespace Base
{
// 抽象基类,封装通用动画逻辑
public abstract class BaseAnimator : MonoBehaviour, ITick
{
// 通用公开字段(可在编辑器中设置)
[SerializeField] protected Sprite[] _sprites; // 动画精灵序列
[SerializeField] protected float _fps = 2; // 每秒帧数
[SerializeField] protected Sprite _staticSprite; // 暂停时的静态精灵
// 通用内部状态
protected bool _isPaused; // 暂停状态
protected float _frameTimer; // 帧计时器
protected int _currentFrameIndex; // 当前帧索引
// 抽象方法:子类必须实现以获取并验证其特有的显示组件
protected abstract void ValidateComponent();
// 抽象方法子类必须实现以设置实际显示组件的Sprite
protected abstract void SetDisplaySprite(Sprite sprite);
protected virtual void Awake()
{
ValidateComponent(); // 子类获取组件
ValidateStartFrame(); // 初始化第一帧
}
// ITick接口实现
public void Tick()
{
var deltaTime = Time.deltaTime;
if (_isPaused)
{
HandlePausedState();
return;
}
PlayAnimation(deltaTime);
}
protected void ValidateStartFrame()
{
// 确保有精灵时可显示有效帧
if (_sprites != null && _sprites.Length > 0)
{
_currentFrameIndex = Mathf.Clamp(_currentFrameIndex, 0, _sprites.Length - 1);
SetDisplaySprite(_sprites[_currentFrameIndex]); // 调用抽象方法设置Sprite
}
else
{
SetDisplaySprite(null); // 调用抽象方法清空Sprite
}
}
protected void HandlePausedState()
{
// 优先使用静态精灵,否则保持当前帧
if (_staticSprite)
{
SetDisplaySprite(_staticSprite); // 调用抽象方法设置Sprite
}
// 否则保持当前显示的Sprite不需要额外操作SetDisplaySprite已在NextFrame中设置
}
protected void PlayAnimation(float deltaTime)
{
if (_sprites == null || _sprites.Length == 0)
{
// 如果没有精灵确保显示组件的Sprite被清除
SetDisplaySprite(null);
return;
}
// 更新帧计时器
_frameTimer += deltaTime;
var frameDuration = 1f / _fps;
// 检查帧切换条件
while (_frameTimer >= frameDuration)
{
_frameTimer -= frameDuration;
NextFrame();
}
}
protected void NextFrame()
{
if (_sprites == null || _sprites.Length == 0) return;
// 循环播放动画
_currentFrameIndex = (_currentFrameIndex + 1) % _sprites.Length;
SetDisplaySprite(_sprites[_currentFrameIndex]); // 调用抽象方法更新Sprite
}
// 外部控制方法
public void SetPaused(bool paused) => _isPaused = paused;
public void SetSprites(Sprite[] newSprites)
{
_sprites = newSprites;
// 如果有新的精灵数组,则立即显示第一帧
if (_sprites != null && _sprites.Length > 0)
{
_currentFrameIndex = 0; // 重置当前帧索引为第一帧
SetDisplaySprite(_sprites[_currentFrameIndex]); // 立即显示第一帧
}
else
{
SetDisplaySprite(null); // 如果没有精灵,则清空渲染器
}
// 重置帧计时器,以确保从头开始播放
_frameTimer = 0f;
}
public void Restore()
{
_currentFrameIndex = 0;
if (_sprites != null && _sprites.Length > 0)
{
SetDisplaySprite(_sprites[_currentFrameIndex]); // 恢复到第一帧
}
else
{
SetDisplaySprite(null);
}
}
public void SetFPS(float newFPS) => _fps = Mathf.Max(0.1f, newFPS);
public void SetStaticSprite(Sprite sprite) => _staticSprite = sprite;
}
}