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

Unity:角色防悬崖掉落的平滑移动实现方案技术问询

角色边缘平滑防掉落实现方案

核心思路

放弃直接停止移动的粗暴逻辑,通过左右两侧的地面射线检测判断悬崖位置,将玩家的输入方向投影到安全的地面区域,实现沿边缘的平滑滑动。

具体实现步骤

1. 优化射线检测逻辑

从角色胶囊体的左右两侧(稍向前偏移,避免检测自身脚下)向下发射射线,判断两侧是否存在悬崖:

// 射线配置参数,可根据角色尺寸调整
float rayLength = 2f;
LayerMask groundLayer = LayerMask.GetMask("Ground"); // 替换为你的地面层
Vector3 capsuleCenter = charController.bounds.center;
float sideOffset = charController.radius + 0.1f; // 射线起点超出胶囊体,避免被自身遮挡
float forwardOffset = 0.5f; // 射线向前偏移,提前检测前方边缘

// 左侧射线检测
Vector3 leftRayOrigin = capsuleCenter + (-transform.right * sideOffset) + (transform.forward * forwardOffset);
bool facingDropLeft = !Physics.Raycast(leftRayOrigin, Vector3.down, rayLength, groundLayer);

// 右侧射线检测
Vector3 rightRayOrigin = capsuleCenter + (transform.right * sideOffset) + (transform.forward * forwardOffset);
bool facingDropRight = !Physics.Raycast(rightRayOrigin, Vector3.down, rayLength, groundLayer);

// 调试可视化(可选)
Debug.DrawRay(leftRayOrigin, Vector3.down * rayLength, facingDropLeft ? Color.red : Color.green);
Debug.DrawRay(rightRayOrigin, Vector3.down * rayLength, facingDropRight ? Color.red : Color.green);

可选优化:用Physics.SphereCast替代Raycast,适配角色胶囊体的碰撞范围,减少小台阶或凸起导致的误判。

2. 平滑调整移动方向

不再直接清零速度,而是根据悬崖位置截断输入方向中危险的分量,保留沿边缘的合法移动:

velocityXZ = inputDir * playerSpeed;

// 左侧无地面:移除向左的移动分量
if (facingDropLeft && !facingDropRight) {
    float leftMovementAmount = Vector3.Dot(velocityXZ, -transform.right);
    if (leftMovementAmount > 0) {
        velocityXZ -= (-transform.right) * leftMovementAmount;
    }
}
// 右侧无地面:移除向右的移动分量
else if (facingDropRight && !facingDropLeft) {
    float rightMovementAmount = Vector3.Dot(velocityXZ, transform.right);
    if (rightMovementAmount > 0) {
        velocityXZ -= transform.right * rightMovementAmount;
    }
}
// 两侧均无地面:完全停止水平移动(避免掉落)
else if (facingDropLeft && facingDropRight) {
    velocityXZ = Vector3.zero;
}

// 后续逻辑保持不变
velocity = new Vector3(velocityXZ.x, velocity.y, velocityXZ.z);

// handle gravity

charController.Move(velocity * Time.deltaTime);

3. 额外优化建议

  • 添加平滑过渡:用Vector3.Lerp将调整后的速度与原速度做插值,避免方向突变:
    velocityXZ = Vector3.Lerp(velocityXZ, adjustedVelocityXZ, Time.deltaTime * 8f);
    
  • 动态调整射线偏移:根据角色移动速度修改forwardOffset,速度越快偏移越大,提前预判边缘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:21:57