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

Unity中按下G键首次无法触发缩放的问题及优化需求

解决Unity缩放脚本首次按G键无反应的问题

问题根源

当前脚本的核心问题是初始scaleUp状态与物体实际缩放不匹配:
比如默认物体尺寸是maxSize,但scaleUp初始值为false。第一次按G键时,Scale()方法先执行scaleUp = !scaleUp将其改为true,接着触发的是缩放到maxSize——和当前尺寸完全一致,自然看不出变化。第二次按G键时scaleUp变回false,才会缩放到minSize,产生可见效果。

解决方案

通过初始化scaleUp状态匹配物体当前缩放,同时优化协程逻辑,确保首次按键就能触发正确的缩放方向:

using System.Collections;
using UnityEngine;

public class Scaling : MonoBehaviour
{
    public GameObject objectToScale;
    public float duration = 1f;
    public Vector3 minSize;
    public Vector3 maxSize;
    public bool scaleUp = false;
    public Coroutine scaleCoroutine;

    public bool automatic = false;
    public bool coroutineIsRunning = false;

    private void Start()
    {
        // 初始化scaleUp状态,匹配物体当前缩放
        if (objectToScale.transform.localScale == maxSize)
        {
            scaleUp = true;
        }
        else if (objectToScale.transform.localScale == minSize)
        {
            scaleUp = false;
        }
        // 若物体初始尺寸在min和max之间,默认准备缩放到max
        else
        {
            scaleUp = false;
        }
    }

    private void Update()
    {
        if (automatic)
        {
            if (!coroutineIsRunning)
            {
                Scale();
            }
        }
        else
        {
            if (Input.GetKeyDown(KeyCode.G))
            {
                Scale();
            }
        }
    }

    private void Scale()
    {
        scaleUp = !scaleUp;

        if (scaleCoroutine != null)
            StopCoroutine(scaleCoroutine);

        if (scaleUp)
        {
            scaleCoroutine = StartCoroutine(ScaleOverTime(objectToScale, maxSize, duration));
        }
        else
        {
            scaleCoroutine = StartCoroutine(ScaleOverTime(objectToScale, minSize, duration));
        }
    }

    private IEnumerator ScaleOverTime(GameObject targetObj, Vector3 toScale, float duration)
    {
        float counter = 0;
        Vector3 startScaleSize = targetObj.transform.localScale;

        coroutineIsRunning = true;

        while (counter < duration)
        {
            counter += Time.deltaTime;
            // 限制进度不超过1,避免过度缩放
            float progress = Mathf.Clamp01(counter / duration);
            targetObj.transform.localScale = Vector3.Lerp(startScaleSize, toScale, progress);

            yield return null;
        }
        // 协程结束后再标记为未运行,确保自动缩放逻辑正确
        coroutineIsRunning = false;
        // 强制设置到目标尺寸,解决Lerp精度偏差问题
        targetObj.transform.localScale = toScale;
    }
}

关键修改说明

  1. Start()初始化逻辑:根据物体初始缩放值设置scaleUp的初始状态,保证第一次按G键时,切换的方向对应正确的缩放目标。
  2. 协程优化:
    • 用Mathf.Clamp01限制进度值,避免因counter超过duration导致的异常缩放。
    • 协程循环结束后再设置coroutineIsRunning = false,避免原代码中提前标记导致自动缩放逻辑出错。
    • 最后强制设置物体到目标尺寸,解决Lerp因浮点精度问题无法完全到达目标的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:32:29