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

Unity开发中玩家触碰物体后触发自主持续异常移动问题求助

你遇到的这个问题核心是混用了Transform直接操作和Rigidbody物理体系,两者逻辑冲突才会产生碰撞后残留速度、自主漂移的情况。

修复方案

  • 首先把所有和物理、位移、旋转相关的逻辑从Update移到FixedUpdate方法中:Update的执行频率随设备帧率波动,和物理引擎固定的更新频率不同步,直接操作Transform很容易导致物理引擎计算出额外的动量残留。
  • 放弃transform.Translate实现移动,改用Rigidbody自带的位移方法,比如MovePosition或者直接修改velocity,所有操作走Rigidbody的API才能和物理引擎的计算逻辑对齐,不会产生异常的额外速度。
  • 直接在Rigidbody组件的Inspector面板勾选Freeze Rotation下的X、Z轴,不需要在代码里强制修改eulerAngles锁旋转,直接改Transform的旋转同样会和物理引擎的旋转计算发生冲突。
  • 补充落地判断的校验逻辑:当前只要发生碰撞就会判定为落地,碰到墙面、其他物体这类非地面对象也会触发跳越判定,建议给地面单独设置专属Layer,碰撞时先判断碰撞对象的Layer再修改isOnGround状态。

修改后参考代码

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

public class PlayerController : MonoBehaviour
{
    public float playerSpeed = 3f;
    private Rigidbody playerRb;
    public GameObject cameraRotation;
    // 可以在Inspector面板指定地面的Layer
    public LayerMask groundLayer;

    void Start()
    {
        playerRb = GetComponent<Rigidbody>();
    }

    float verticalInput;
    float horizontalInput;
    bool isOnGround = true;

    // 输入检测放在Update,避免漏判按键
    void Update()
    {
        verticalInput = Input.GetAxis("Vertical");
        horizontalInput = Input.GetAxis("Horizontal");

        if (Input.GetKeyDown(KeyCode.Space) && isOnGround)
        {
            playerRb.AddForce(Vector3.up * 10, ForceMode.Impulse);
            isOnGround = false;
        }
    }

    // 物理相关操作全部放在FixedUpdate
    private void FixedUpdate()
    {
        // 基于相机朝向计算移动方向
        Vector3 moveDir = cameraRotation.transform.forward * verticalInput + cameraRotation.transform.right * horizontalInput;
        moveDir.y = 0;
        moveDir.Normalize();

        // 用Rigidbody做位移,不走Transform
        playerRb.MovePosition(transform.position + moveDir * playerSpeed * Time.fixedDeltaTime);

        // 同步玩家朝向到相机Y轴
        playerRb.rotation = Quaternion.Euler(0, cameraRotation.transform.eulerAngles.y, 0);
    }

    private void OnCollisionEnter(Collision collision)
    {
        // 只有碰到地面才判定落地
        if (((1 << collision.gameObject.layer) & groundLayer) != 0)
        {
            isOnGround = true;
        }
    }
}

修改完成后重新测试,碰撞后自主漂移的问题基本就会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:06:04