You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何遍历精灵数组实现角色跑步动画?(Unity开发)

解决Unity精灵数组循环播放跑步动画的问题

首先补充CustomAnimation的定义(你代码里未给出,需包含精灵数组和帧率参数):

[System.Serializable]
public class CustomAnimation
{
    public Sprite[] sprites;
    public float frameRate = 0.15f; // 动画帧率,可在Inspector面板调整
}

方法一:使用协程(Coroutine)

协程是Unity中实现帧动画的常用方案,能便捷控制每帧的时间间隔,且不阻塞主线程。

修改CharacterData类,在Load方法中启动协程循环切换精灵:

public class CharacterData : MonoBehaviour 
{
    [SerializeField] private Character _data; 
    [SerializeField] private SpriteRenderer spriteRenderer; 
    private Coroutine _runAnimCoroutine; // 保存协程引用,用于停止动画

    public void Load(Character data)
    {
        _data = data; 
        // 先停止之前的动画(如果存在)
        if (_runAnimCoroutine != null)
        {
            StopCoroutine(_runAnimCoroutine);
        }
        // 启动跑步动画协程
        _runAnimCoroutine = StartCoroutine(PlayRunAnimationLoop());
    }

    private IEnumerator PlayRunAnimationLoop()
    {
        // 空值检查,避免空引用报错
        if (_data.run == null || _data.run.sprites == null || _data.run.sprites.Length == 0)
        {
            yield break;
        }

        int currentFrameIndex = 0;
        float frameInterval = 1f / _data.run.frameRate; // 计算每帧的时间间隔

        while (true) // 无限循环播放动画
        {
            spriteRenderer.sprite = _data.run.sprites[currentFrameIndex];
            // 循环更新帧索引
            currentFrameIndex = (currentFrameIndex + 1) % _data.run.sprites.Length;
            // 等待指定时间后切换下一帧
            yield return new WaitForSeconds(frameInterval);
        }
    }

    // 可选:提供停止跑步动画的方法
    public void StopRunAnimation()
    {
        if (_runAnimCoroutine != null)
        {
            StopCoroutine(_runAnimCoroutine);
            _runAnimCoroutine = null;
        }
    }
}

方法二:使用Update计时

如果不想用协程,也可以在Update方法中通过计时器控制帧切换:

public class CharacterData : MonoBehaviour 
{
    [SerializeField] private Character _data; 
    [SerializeField] private SpriteRenderer spriteRenderer; 
    private int _currentFrameIndex;
    private float _frameTimer;

    public void Load(Character data)
    {
        _data = data; 
        _currentFrameIndex = 0;
        _frameTimer = 0f;

        // 初始化显示第一帧
        if (_data.run != null && _data.run.sprites != null && _data.run.sprites.Length > 0)
        {
            spriteRenderer.sprite = _data.run.sprites[_currentFrameIndex];
        }
    }

    private void Update()
    {
        // 空值检查
        if (_data == null || _data.run == null || _data.run.sprites == null || _data.run.sprites.Length == 0)
        {
            return;
        }

        float frameInterval = 1f / _data.run.frameRate;
        _frameTimer += Time.deltaTime;

        // 当计时器达到帧间隔时,切换下一帧
        if (_frameTimer >= frameInterval)
        {
            _frameTimer -= frameInterval; // 重置计时器,避免累积误差
            _currentFrameIndex = (_currentFrameIndex + 1) % _data.run.sprites.Length;
            spriteRenderer.sprite = _data.run.sprites[_currentFrameIndex];
        }
    }
}

为什么直接用for循环不行?

for循环是在单帧内同步执行的,会瞬间遍历完所有精灵,肉眼无法捕捉中间的切换过程,最终只会显示最后一次设置的精灵。必须通过时间间隔逐帧切换,让每帧的显示停留足够时间,才能形成连续的动画效果。

内容的提问来源于stack exchange,提问作者Михаил Горбунов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:13:10