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

Unity中如何让Transform平滑移动时通过Lerp同步实现缩放?

问题原因
  1. 缩放Lerp参数错误:你当前缩放Lerp的起始值用的是每帧更新的transform.localScale,而非进入Transferring状态时的固定初始缩放值,导致缩放变化速率和位置Lerp的线性速率不匹配,前期缩放幅度极小几乎不可见,视觉上表现为移动结束才开始缩放。
  2. 无时长控制与过冲保护:你声明的lerpTime参数未实际使用,timer直接累加不做上限限制,当timer超过1时Lerp会输出超出目标值的结果,最终缩放值小于预期。
  3. 父子物体转换导致缩放偏移:设置父物体时Unity默认会保持物体的世界缩放,localScale会自动根据父物体的缩放系数换算,进一步导致最终缩放值和你设置的0.001不符。
修复代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Manager : MonoBehaviour
{
    public enum TransitionState
    {
        None,
        MovingTowards,
        Transferring
    }

    public Transform player;
    public Transform carte;
    public Animation anim;
    public Transform destinationTransform;
    public float speed;
    public float distanceToStop;
    public float lerpTime;
    public UnlockCrate unlockCarte;

    private GameObject rig_f_middle;
    private Transform originTransform;
    // 新增:记录进入Transferring状态时的初始缩放
    private Vector3 originalScale;
    private float timer;
    private bool openonce = false;

    private TransitionState state = TransitionState.MovingTowards;

    void Start()
    {
        rig_f_middle = GameObject.Find("rig_f_middle.02.R");
    }

    void Update()
    {
        var dist = Vector3.Distance(carte.position, player.position);


        if(dist < 1.5f)
        {
            if (openonce == false)
            {
                anim.Play("Crate_Open");
                openonce = true;
            }

            switch (state)
            {
                case TransitionState.MovingTowards:
                    var v = rig_f_middle.transform.position - transform.position;
                    if (v.magnitude < 0.001f)
                    {
                        state = TransitionState.Transferring;
                        originTransform = rig_f_middle.transform;
                        // 进入Transferring状态时记录初始位置和初始缩放
                        originalScale = transform.localScale;
                        timer = 0;
                        return;
                    }
                    Vector3 moveDir = v.normalized;
                    transform.position += moveDir * speed * Time.deltaTime;
                    break;

                case TransitionState.Transferring:
                    timer += Time.deltaTime;
                    // 归一化时间,限制在0-1区间避免过冲
                    float t = Mathf.Clamp01(timer / lerpTime);
                    // 位置和缩放用同一个t值,保证完全同步
                    this.transform.position = Vector3.Lerp(originTransform.position, destinationTransform.position, t);
                    this.transform.localScale = Vector3.Lerp(originalScale, new Vector3(0.001f, 0.001f, 0.001f), t);
                    if (t >= 1.0f)
                    {
                        this.transform.parent = destinationTransform;
                        // 设置父物体后手动赋值缩放值,避免父物体缩放影响
                        this.transform.localScale = new Vector3(0.001f, 0.001f, 0.001f);
                        state = TransitionState.None;
                        this.enabled = false;
                        return;
                    }
                    break;

                default:
                    this.enabled = false;
                    return;
            }
        }
    }
}
关键修改说明
  • 新增originalScale变量,记录进入Transferring阶段时的物体初始缩放,作为缩放Lerp的固定起始值,保证缩放变化和位置Lerp的速率完全同步
  • 新增时间归一化逻辑,使用你声明的lerpTime参数控制整个Transferring阶段的动画时长,同时用Mathf.Clamp01限制时间系数不超过1,避免Lerp过冲导致缩放值小于预期
  • 完成父物体设置后手动重设localScale为0.001,抵消父物体缩放带来的数值偏移

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 02:27:02