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

Unity中RigidBody受挤压穿模、异常飞动问题如何解决

Unity FPS玩家被挤压时异常飞起、穿模问题修复

问题描述

在Unity中开发第一人称射击游戏时,玩家对象已挂载胶囊碰撞体(Capsule Collider)与Rigidbody组件,出现如下异常:玩家在狭小空间被两个物体挤压时,会无规律飞起、出现碰撞穿模,不符合设计预期。
当前使用的玩家控制器代码如下:

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

public class fpsController : MonoBehaviour
{
    public InputMaster inputMaster;
    private Rigidbody rig;
    public Vector2 inputVector;
    public Transform groundcheck;
    public bool isGrounded;
    float speed = 6f;
    public LayerMask whatisgorund;
    void Awake()
    {
        inputMaster = new InputMaster();
        inputMaster.player.Enable();
        inputMaster.player.Jump.performed += Jump;
        inputMaster.player.primaryuse.performed += PrimaryUse;
        rig = GetComponent<Rigidbody>();
    }
    void Update()
    {
        inputVector = inputMaster.player.movement.ReadValue<Vector2>().normalized;
    }
    public void FixedUpdate()
    {
        isGrounded = Physics.CheckSphere(groundcheck.position, 0.5f, whatisgorund);
        Vector3 move = transform.right * inputVector.x + transform.forward * inputVector.y;
        transform.position = rig.position + speed * Time.deltaTime * move;
    }

    public void Jump(InputAction.CallbackContext context)
    {
        if (context.performed && isGrounded)
        {
            rig.AddForce(Vector3.up * 5, ForceMode.Impulse);
        }

    }
    public void PrimaryUse(InputAction.CallbackContext context)
    {
        if (isGrounded && context.performed)
        {

        }
    }
}

玩家对象配置参考:
玩家对象Inspector面板配置

核心问题原因

穿模、弹飞的根因是移动逻辑违反了Unity物理系统的规则:对挂载Rigidbody的物体直接修改transform.position,会完全绕过物理引擎的碰撞解算流程,Rigidbody的物理模拟和直接改位置的逻辑产生冲突,挤压时碰撞解算产生的冲量没有被正确释放,就会把玩家弹飞,或者直接穿过碰撞体。

修复步骤

  1. 重写移动逻辑,使用Rigidbody官方接口移动
    删掉FixedUpdate里直接修改transform.position的代码,改用Rigidbody.MovePosition()完成移动,该接口会把移动请求提交给物理引擎,统一计算碰撞响应。同时物理帧逻辑统一使用Time.fixedDeltaTime,不要混用Time.deltaTime避免帧率导致的计算误差:
    public void FixedUpdate()
    {
        isGrounded = Physics.CheckSphere(groundcheck.position, 0.5f, whatisgorund);
        Vector3 move = transform.right * inputVector.x + transform.forward * inputVector.y;
        // 替换原直接修改transform.position的逻辑
        rig.MovePosition(rig.position + speed * Time.fixedDeltaTime * move);
    }
    
  2. 修正Rigidbody组件参数
    • 将Collision Detection从默认的Discrete改为Continuous,高速移动下可改为Continuous Dynamic,大幅降低穿模概率
    • 将Interpolate设置为Interpolate,解决刚体移动的视觉抖动问题
    • 勾选Freeze Rotation下的X、Y、Z三个轴,避免碰撞时玩家模型出现非预期旋转
    • 保持Is Kinematic为关闭状态,开启后刚体不会响应碰撞力
  3. 添加异常速度钳制,彻底解决挤压弹飞
    碰撞解算偶发的异常冲量会给刚体施加远超正常值的垂直速度,在FixedUpdate里添加速度钳制逻辑即可:
    // 放在FixedUpdate末尾,根据自己的跳跃力调整阈值,示例中5的冲量跳跃对应最大上升速度约7
    if (rig.velocity.y > 7f)
    {
        rig.velocity = new Vector3(rig.velocity.x, 7f, rig.velocity.z);
    }
    
  4. 碰撞体精度校准
    调整Capsule Collider的半径、高度参数,确保碰撞体完全包裹玩家模型,不要留过大缝隙也不要小于模型体积;地面检测的CheckSphere半径控制在0.3-0.5区间,避免半径过大误判周围碰撞体为地面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:24:26