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

Unity中如何基于Sprite列表实现幸运转盘动画?

解决Unity协程中Sprite切换减速不生效的问题

你的问题核心在于WaitForSeconds的等待时长是创建时就固定的,如果只是递增一个变量但没有每次生成新的WaitForSeconds实例,协程会一直用最初的等待时间,自然无法实现减速效果。下面是正确的实现思路和代码:

核心思路

  1. 计算初始与目标的切换间隔:初始间隔是1/30秒(每秒30次),目标间隔是1秒(每秒1次),总减速时长7秒。
  2. 用线性插值(Mathf.Lerp)在7秒内平滑过渡间隔值,每次循环都计算当前应等待的时长,并生成新的WaitForSeconds。
  3. 基于Time.time跟踪已流逝的时间,确保减速过程的准确性。

完整实现代码

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SpriteAnimator : MonoBehaviour
{
    public IEnumerator AnimateDeceleratingSprites(SpriteRenderer spriteRenderer, List<Sprite> spriteList)
    {
        // 边界检查,避免空引用报错
        if (spriteRenderer == null || spriteList == null || spriteList.Count == 0)
            yield break;

        float startInterval = 1f / 30f;
        float targetInterval = 1f;
        float totalDecelerationTime = 7f;
        float animationStartTime = Time.time;
        int currentSpriteIndex = 0;

        while (true)
        {
            // 切换到下一个Sprite
            spriteRenderer.sprite = spriteList[currentSpriteIndex];
            currentSpriteIndex = (currentSpriteIndex + 1) % spriteList.Count;

            // 计算已流逝的时间和当前应等待的间隔
            float elapsedTime = Time.time - animationStartTime;
            float progress = Mathf.Clamp01(elapsedTime / totalDecelerationTime);
            float currentWaitInterval = Mathf.Lerp(startInterval, targetInterval, progress);

            // 等待当前计算出的间隔(必须每次生成新的WaitForSeconds)
            yield return new WaitForSeconds(currentWaitInterval);

            // 当减速完成后停止协程
            if (progress >= 1f && Mathf.Approximately(currentWaitInterval, targetInterval))
                break;
        }

        // 可选:动画结束后停在第一个Sprite
        spriteRenderer.sprite = spriteList[0];
    }
}

关键细节说明

  • 每次生成新的WaitForSeconds:不能复用同一个WaitForSeconds对象,因为它的等待时长在创建时就已确定,后续修改变量不会改变它的行为。
  • 用Time.time跟踪进度:确保减速过程不受帧率波动影响,始终按照实际时间平滑过渡。
  • 边界检查:提前处理空引用情况,避免运行时报错。
  • 进度限制:用Mathf.Clamp01确保进度值始终在0-1之间,防止超过目标间隔。

调用方式

在你的脚本中启动协程即可:

// 假设你有SpriteRenderer组件和Sprite列表
public SpriteRenderer targetRenderer;
public List<Sprite> sprites;

void Start()
{
    StartCoroutine(AnimateDeceleratingSprites(targetRenderer, sprites));
}

内容的提问来源于stack exchange,提问作者tumhaarajeeja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:22:41