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

Unity角色下落碰撞墙体后停止下落问题求助

问题分析与解决方案

你的问题核心是直接赋值刚体水平速度干扰了物理引擎的碰撞响应:当角色下落时贴向墙体,强制的水平速度会导致物理系统为修正穿透,意外清零y轴下落动量。以下是针对性的解决思路和优化方案:

一、替换直接赋值为物理力驱动(推荐)

直接覆盖rb.velocity会绕过Unity物理引擎的碰撞逻辑,改用AddForce让引擎自然处理碰撞后的速度调整,从根源避免动量丢失:

void Update()
{
    float xMove = Input.GetAxisRaw("Horizontal");
    float zMove = Input.GetAxisRaw("Vertical");

    // 归一化输入方向,避免斜向移动速度过快
    Vector3 moveDir = new Vector3(xMove, 0, zMove).normalized;
    Vector3 targetVelocity = moveDir * movSpeed * speedMult;
    
    // 只计算水平方向的速度增量,保留原有y轴下落速度
    Vector3 velocityDelta = targetVelocity - new Vector3(rb.velocity.x, 0, rb.velocity.z);
    
    // 用VelocityChange模式直接修改速度,兼顾即时移动手感与物理逻辑
    rb.AddForce(velocityDelta, ForceMode.VelocityChange);
}

二、平滑过渡水平速度,减少物理冲突

如果想保留直接控制速度的手感,用平滑插值替代硬赋值,给物理引擎留出处理碰撞的缓冲空间:

public float moveAcceleration = 12f; // 可调整的加速度参数,控制移动平滑度

void Update()
{
    float xMove = Input.GetAxisRaw("Horizontal");
    float zMove = Input.GetAxisRaw("Vertical");

    float targetXSpeed = xMove * movSpeed * speedMult;
    float targetZSpeed = zMove * movSpeed * speedMult;

    // 平滑过渡到目标水平速度,避免突变导致的物理穿透
    float newXSpeed = Mathf.MoveTowards(rb.velocity.x, targetXSpeed, moveAcceleration * Time.deltaTime);
    float newZSpeed = Mathf.MoveTowards(rb.velocity.z, targetZSpeed, moveAcceleration * Time.deltaTime);

    rb.velocity = new Vector3(newXSpeed, rb.velocity.y, newZSpeed);
}

三、排查物理设置与其他脚本

  1. 刚体配置检查:
    • 将角色Rigidbody的Collision Detection设为Continuous Dynamic,减少高速移动时的穿透概率
    • 确保Constraints未锁定Y轴,且Mass、Drag参数合理(Drag过高会导致速度异常衰减)
  2. 碰撞体检查:
    • 角色使用CapsuleCollider(贴合人形角色的碰撞范围),墙体使用BoxCollider并标记为Static
    • 避免角色与墙体的碰撞体初始重叠
  3. 其他脚本排查:
    • 检查是否有地面检测、碰撞触发类脚本,误将贴墙状态判定为地面接触,从而错误清零Y轴速度

四、替代方案:提前碰撞检测

如果想主动避免嵌入墙体,可以用Physics.CapsuleCast提前检测移动路径,有障碍物时停止对应方向的移动:

void Update()
{
    float xMove = Input.GetAxisRaw("Horizontal");
    float zMove = Input.GetAxisRaw("Vertical");

    Vector3 moveDir = new Vector3(xMove, 0, zMove).normalized;
    float moveDistance = movSpeed * speedMult * Time.deltaTime;

    // 获取角色胶囊碰撞体的检测参数
    CapsuleCollider capsule = GetComponent<CapsuleCollider>();
    Vector3 start = transform.position + capsule.center + Vector3.up * (-capsule.height/2 + capsule.radius);
    Vector3 end = start + Vector3.up * (capsule.height - 2*capsule.radius);

    // 检测移动方向是否有障碍物,无障碍物时才执行移动
    if (!Physics.CapsuleCast(start, end, capsule.radius, moveDir, moveDistance))
    {
        rb.velocity = new Vector3(moveDir.x * movSpeed * speedMult, rb.velocity.y, moveDir.z * movSpeed * speedMult);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 17:27:35