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

Unity中如何让Rigidbody斜撞墙体时实现正确滑动效果?

解决Rigidbody斜向撞墙停止而非滑动的问题

优先尝试物理材质调整(最简方案)

  • 给玩家的Capsule Collider和地图立方体的Collider都添加物理材质(Physic Material)
  • 调整物理材质参数:
    • 将Dynamic Friction和Static Friction均设为0,彻底消除摩擦力以保证滑动顺畅
    • Bounciness设为0,避免碰撞反弹干扰移动逻辑
    • 把Friction Combine和Bounce Combine设为Minimum,取接触物体中摩擦力最小的参数生效

物理材质无效时,手动处理碰撞速度修正

若物理材质因Rigidbody的力施加逻辑冲突失效,可手动过滤碰撞后的速度分量:

  1. 通过OnCollisionStay和OnCollisionExit记录碰撞状态与碰撞面法线
  2. 碰撞发生时,将当前速度分解为平行于墙面和垂直于墙面的分量
  3. 保留平行于墙面的速度分量,丢弃垂直方向分量,重新赋值给Rigidbody

示例代码片段:

private Vector3 _lastCollisionNormal;
private bool _isColliding;

void OnCollisionStay(Collision collision)
{
    _isColliding = true;
    // 取首个接触点法线作为墙面法线(多接触点可取平均)
    _lastCollisionNormal = collision.contacts[0].normal;
}

void OnCollisionExit(Collision collision)
{
    _isColliding = false;
}

private void SimpleMove()
{
    // 保留原有移动逻辑...

    // 碰撞时修正速度
    if (_isColliding)
    {
        var currentVelocity = _rigidbody.velocity;
        // 移除垂直于碰撞面的速度分量
        var parallelVelocity = Vector3.ProjectOnPlane(currentVelocity, _lastCollisionNormal);
        // 保持原移动速度大小(可根据需求调整)
        parallelVelocity = parallelVelocity.normalized * scaledMovementSpeed;
        // 保留Y轴速度(如跳跃下落)
        parallelVelocity.y = currentVelocity.y;
        _rigidbody.velocity = parallelVelocity;
    }
}

移动逻辑小优化

当前velocityChange基于transform.forward计算,可改为用SimpleMoveVector方向计算,避免转向延迟带来的方向偏差(你提到即时转向后问题依旧,此为次要优化):

// 替换原velocityChange计算逻辑
var targetVelocity = new Vector3(SimpleMoveVector.x * scaledMovementSpeed, velocity.y, SimpleMoveVector.z * scaledMovementSpeed);
var velocityChange = targetVelocity - velocity;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 23:05:16