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

类似原神的3D游戏自由攀爬系统边缘攀爬及斜墙检测问题求助

边缘攀爬系统问题修复方案

一、射线检测逻辑优化(解决斜墙失效、误判问题)

当前双射线只适配垂直墙面,斜墙时垂直向下射线路径不对,直接空射。得改这几点:

  • 第二个射线别用世界空间的Vector3.down,改成沿墙面法线的垂直向下方向投射——也就是墙面的“下”方向,这样斜墙边缘才能被检测到。
  • 加个LayerMask只检测攀爬层,避免误触地面、道具这些无关物体。
  • 用角色碰撞体中心当检测起点,别用transform.position,模型偏移会导致检测不准。

修改后的示例代码:

[SerializeField] private LayerMask climbLayer; // 拖拽攀爬层到这里
[SerializeField] private CapsuleCollider playerCollider;

private bool edgeDetect()
{
    RaycastHit firstHit;
    // 用碰撞体中心做检测起点,更贴合角色实际位置
    Vector3 position = playerCollider.bounds.center + detectionOffcet;

    // 只检测指定攀爬层,排除干扰
    if (Physics.Raycast(position, transform.forward, out firstHit, 2f, climbLayer))
    {
        // 第二个射线起点:沿墙面法线向上偏移,适配斜墙的边缘高度
        Vector3 secondRayStart = firstHit.point + transform.forward * playerRadius + firstHit.normal * (0.6f * playerHeight);
        // 第二个射线方向:沿墙面的垂直向下方向(投影掉法线的垂直分量)
        Vector3 secondRayDir = -Vector3.ProjectOnPlane(firstHit.normal, Vector3.up).normalized;
        
        // 拉长射线长度,适配斜墙的边缘跨度
        if (Physics.Raycast(secondRayStart, secondRayDir, out var secondHit, playerHeight * 1.5f, climbLayer))
        {
            Targetposition = secondHit.point + edgeOffcet;
            m_Animator.SetTrigger("edge");
            // 目标位置加碰撞体中心偏移,避免角色模型悬空
            Vector3 climbEnd = secondHit.point + playerCollider.center;
            // 调整MatchTarget的时间窗口和权重,让动画过渡更平滑
            m_Animator.MatchTarget(climbEnd, Quaternion.LookRotation(-firstHit.normal), 
                AvatarTarget.Root, 
                new MatchTargetWeightMask(new Vector3(1, 1, 0), 0), // 只匹配位置,忽略旋转权重
                0.1f, 0.8f); // 覆盖动画主要攀爬阶段,别搞太短
            return true;
        }
    }
    return false;
}

二、角色状态与动画控制(解决坠落、卡顿问题)

  • 触发边缘攀爬时,立刻禁用角色重力+锁死移动输入,物理引擎的坠落力和动画驱动冲突就是卡顿的根源。可以设rigidbody.isKinematic = true,或者关重力rigidbody.useGravity = false,动画播完再恢复。
  • 别用0到0.09f这么短的MatchTarget时间窗口,动画刚启动就结束匹配,角色根本来不及到位。改成0.1f到0.8f,覆盖动画的核心攀爬动作阶段。
  • 动画状态机里锁死状态:播放边缘攀爬动画时,禁止切换到坠落、移动状态,避免频繁状态跳变导致卡顿——比如给edge状态设Exit Time为1,或者用布尔参数控制过渡。

三、斜墙适配细节

  • 角色旋转别直接用Quaternion.LookRotation(-firstHit.normal),斜墙法线不是水平的,角色会歪得离谱。先把法线投影到XZ平面再算旋转:
// 只取法线的水平分量做朝向,保证角色直立
Vector3 wallForward = -Vector3.ProjectOnPlane(firstHit.normal, Vector3.up).normalized;
Quaternion targetRot = Quaternion.LookRotation(wallForward, Vector3.up);
  • 动态调整edgeOffcet,用firstHit.normal * 0.1f代替固定值,让角色始终贴紧墙面,不会穿模或悬空。

四、调试技巧

  • 在Scene视图画射线,实时看检测是否准确:加Debug.DrawRay(position, transform.forward * 2f, Color.red)和Debug.DrawRay(secondRayStart, secondRayDir * playerHeight *1.5f, Color.blue),直观看到射线的位置和方向。
  • 打印firstHit.normal和secondHit.point的值,确认斜墙场景下是否正确命中边缘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:05:44