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

Unity 2D角色移动、使用喷气背包或高速度时卡顿,插值优化无效求原因

问题核心原因
  • 你在Update生命周期里同时混用了直接修改transform位置和Rigidbody2D物理力控制两种位移方式,Unity物理引擎的更新是在FixedUpdate中执行的,和Update的执行频率不匹配,两者对位置的修改会互相冲突,速度越高、力的变化越频繁(比如开喷气背包持续加力)的时候,冲突就越明显,自然就会卡顿。
  • 你开启interpolate之后卡顿更严重的原因也和这个有关:Rigidbody的插值是基于物理帧的位置来平滑过渡到渲染帧的,你直接改transform相当于打断了插值的计算逻辑,反而会出现更明显的抖动。
修复方案
  1. 把水平移动的逻辑从直接改transform换成通过Rigidbody控制,不要直接操作transform.position
  2. 所有和Rigidbody相关的参数修改、力添加都放到FixedUpdate里执行,Update只负责收集用户输入
  3. 调整后的代码参考如下:
using UnityEngine;
using UnityEngine.SceneManagement;

public class Player : MonoBehaviour
{
    //基础变量
    [SerializeField]
    private float speed = 5f;

    [SerializeField]
    private float Jumpforce = 5f;

    [SerializeField]
    private float JetPackForce = 5f;

    [SerializeField]
    public bool canUseJetpack = true;

    [SerializeField]
    private Rigidbody2D rb;

    [SerializeField]
    private Animator animator;
  
    private bool isFacingRight = true;
    // 新增变量存储输入状态
    private float horizontalInput;
    private bool jumpPressed;
    private bool jetpackPressed;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    // Update仅负责收集输入、处理动画/翻转等非物理逻辑
    void Update()
    {
        horizontalInput = Input.GetAxis("Horizontal");
        if (Input.GetKeyDown("space") && Mathf.Abs(rb.velocity.y) < 0.001f)
        {
            jumpPressed = true;
        }
        jetpackPressed = Input.GetKey(KeyCode.Q);

        animator.SetFloat("Speed", Mathf.Abs(horizontalInput));

        if (horizontalInput < 0 && isFacingRight)
        {
            flip();
        }
        else if (horizontalInput > 0 && !isFacingRight)
        {
            flip();
        }

        animator.SetBool("UsingJetpack", jetpackPressed && canUseJetpack);

        if (HealthBar.instance.currentHealth <= 0)
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        }
    }

    // 所有物理相关操作统一放到FixedUpdate执行
    private void FixedUpdate()
    {
        // 水平移动改用Rigidbody速度控制
        Vector2 velocity = rb.velocity;
        velocity.x = horizontalInput * speed;
        rb.velocity = velocity;

        if (jumpPressed)
        {
            rb.AddForce(new Vector2(0, Jumpforce), ForceMode2D.Impulse);
            jumpPressed = false;
        }

        if (jetpackPressed && canUseJetpack)
        {
            rb.AddForce(Vector2.up * JetPackForce);
            JetpackBar.instance.UseFuel(0.1f);
        }
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            HealthBar.instance.takeDamage(25);
        }
    }

    void flip()
    {
        isFacingRight = !isFacingRight;
        transform.Rotate(0f, 180f, 0f);
    }
}
  1. 修改完成后可重新开启Rigidbody2D的Interpolation选项,此时插值逻辑不会被打断,移动会更平滑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 22:15:01