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

Unity 2D精灵循环放大效果失效问题求助

Unity 2D精灵循环缩放问题排查与修复

问题根源分析

你的代码无法实现循环缩放效果,核心问题集中在缩放逻辑的实现上:

  • Mathf.Lerp用法错误:Mathf.Lerp(minScale, maxScale, scaleSpeed)中的第三个参数是插值比例(0~1),你传入固定的scaleSpeed(如0.1)只会得到一个固定的中间缩放值,无法实现从min到max的平滑过渡。
  • 无进度跟踪变量:没有记录当前缩放的进度,无法随着时间推进完成完整的缩放周期。
  • 状态切换条件失效:由于Lerp计算出的缩放值永远达不到maxScale或minScale,isScalingUp的状态永远不会切换,循环直接中断。
  • 缩放速度未适配时间:缩放逻辑未乘以Time.deltaTime,导致速度受帧率影响,不同设备表现不一致。

修复后的代码

以下是修正后的完整代码,保留了你原有的淡入淡出逻辑,同时修复了缩放循环的问题:

using UnityEngine;

public class SpriteFader : MonoBehaviour
{
    [SerializeField] private float delayTime = 1f;
    [SerializeField] private float fadeInTime = 1f;
    [SerializeField] private float stayVisibleTime = 5f;
    [SerializeField] private float fadeOutTime = 1f;
    [SerializeField] private AudioClip fadeInSound;
    [SerializeField] private float minScale = 1f;
    [SerializeField] private float maxScale = 1.2f;
    [SerializeField] private float scaleSpeed = 2f; // 调整为基于时间的速度,建议值2~5

    private SpriteRenderer spriteRenderer;
    private float fadeDirection = 1f;
    private float timer = 0f;
    private bool hasFadedIn = false;
    private bool hasStartedFadeOut = false;
    private bool hasStartedDelay = false;
    private AudioSource audioSource;
    private bool isScalingUp = true;
    private float currentScaleProgress = 0f; // 新增:跟踪当前缩放进度(0~1)

    void Start()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
        spriteRenderer.color = new Color(spriteRenderer.color.r, spriteRenderer.color.g, spriteRenderer.color.b, 0f);

        audioSource = gameObject.AddComponent<AudioSource>();
        audioSource.playOnAwake = false;
        audioSource.clip = fadeInSound;
    }

    void Update()
    {
        if (!hasStartedDelay)
        {
            if (timer < delayTime)
            {
                timer += Time.deltaTime;
            }
            else
            {
                hasStartedDelay = true;
                timer = 0f;
                audioSource.Play();
            }
        }
        else if (!hasFadedIn)
        {
            float newAlpha = Mathf.Clamp01(spriteRenderer.color.a + (Time.deltaTime / fadeInTime));
            spriteRenderer.color = new Color(spriteRenderer.color.r, spriteRenderer.color.g, spriteRenderer.color.b, newAlpha);

            if (newAlpha >= 1f)
            {
                hasFadedIn = true;
                isScalingUp = true;
                currentScaleProgress = 0f; // 初始化缩放进度
            }
        }
        else
        {
            if (timer < stayVisibleTime)
            {
                timer += Time.deltaTime;
                
                // 更新缩放进度
                currentScaleProgress += Time.deltaTime * scaleSpeed * (isScalingUp ? 1f : -1f);
                // 限制进度在0~1之间
                currentScaleProgress = Mathf.Clamp01(currentScaleProgress);

                // 根据进度计算当前缩放值
                float currentScale = Mathf.Lerp(minScale, maxScale, currentScaleProgress);
                transform.localScale = new Vector3(currentScale, currentScale, 1f);

                // 切换缩放方向
                if (currentScaleProgress >= 1f)
                {
                    isScalingUp = false;
                }
                else if (currentScaleProgress <= 0f)
                {
                    isScalingUp = true;
                }
            }
            else if (!hasStartedFadeOut)
            {
                hasStartedFadeOut = true;
                fadeDirection = -1f;
                timer = 0f;
            }
            else
            {
                float newAlpha = Mathf.Clamp01(spriteRenderer.color.a + (Time.deltaTime / fadeOutTime * fadeDirection));
                spriteRenderer.color = new Color(spriteRenderer.color.r, spriteRenderer.color.g, spriteRenderer.color.b, newAlpha);

                if (newAlpha <= 0f)
                {
                    Destroy(gameObject);
                }
            }
        }
    }
}

关键修改说明

  1. 新增currentScaleProgress变量:用于跟踪当前缩放的插值进度(0对应minScale,1对应maxScale),实现平滑过渡。
  2. 修正Mathf.Lerp用法:使用currentScaleProgress作为Lerp的第三个参数,随着时间推进动态计算缩放值。
  3. 缩放速度适配时间:currentScaleProgress的更新乘以Time.deltaTime,确保速度不受帧率影响。
  4. 用Mathf.Clamp01限制值范围:避免alpha和缩放进度超出0~1的有效范围,防止异常值导致的逻辑错误。
  5. 调整scaleSpeed的含义:从固定插值比例改为基于时间的速度(建议值2~5,可根据视觉效果调整)。

额外优化建议

  • 如果希望逻辑更清晰,可以将缩放、淡入淡出逻辑拆分为独立的协程(Coroutine),替代Update中的状态判断。
  • 若需要更复杂的动画曲线,可以使用AnimationCurve自定义缩放的缓动效果,替换当前的线性Lerp。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:17:01