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

如何限制水平轴旋转?攀爬墙时旋转跳变问题求助

问题排查与解决方案

先修复触发器的核心逻辑错误

你写的WallClimbing脚本里有个致命错误:OnTriggerEnter的参数是other,但判断条件用了未定义的col——这个条件永远不会触发,isClimbingWall自然一直是false,后续的旋转限制逻辑根本不会生效。先修正这段代码:

// WallClimbing script
public void OnTriggerEnter(Collider other)
{
    if (other.gameObject.CompareTag("Wall")) // 用CompareTag比直接判Tag更高效,还能避免空引用
    {
        isClimbingWall = true;
    }
}

同时记得给墙体对象打上Wall标签,检查触发器和墙体的碰撞体设置(触发器需勾选Is Trigger,双方碰撞体的层交互要正常)。

解决旋转跳变与万向锁问题

你的CameraLook脚本存在两个核心问题,直接导致了旋转异常:

1. 水平旋转限制逻辑矛盾

你先把rotation.x处理成0-360的范围,后面又强制Clamp到-35到35——两个范围完全冲突,比如玩家当前水平旋转是180度,进入攀爬后会被直接拉到35度,必然出现跳变。正确的做法是:进入攀爬时记录当前水平旋转的基准值,之后只允许在基准值的±35度范围内旋转。

2. 旋转组合方式引发万向锁

分开用AngleAxis设置相机和玩家的旋转,欧拉角的顺序问题容易触发万向锁,且这种方式没有考虑旋转的累积逻辑。

修改后的CameraLook脚本示例:

// CameraLook script
public WallClimbing wallClimbing;
public Transform player;
public string xAxis = "Mouse X";
public string yAxis = "Mouse Y";
public float sensitivity = 2f;
public float yRotationLimit = 80f;
public float xRotationLimit = 35f;

private Vector2 rotation = Vector2.zero;
private float climbBaseXRotation; // 记录攀爬时的水平旋转基准

void Update()
{
    Vector2 mouseDelta = new Vector2(Input.GetAxis(xAxis), Input.GetAxis(yAxis));

    // 处理相机垂直旋转
    rotation.y += mouseDelta.y * sensitivity;
    rotation.y = Mathf.Clamp(rotation.y, -yRotationLimit, yRotationLimit);

    // 处理玩家水平旋转
    if (wallClimbing.isClimbingWall)
    {
        // 首次触发攀爬时记录基准旋转
        if (climbBaseXRotation == 0)
        {
            climbBaseXRotation = player.transform.eulerAngles.y;
        }
        // 计算当前旋转与基准的偏移(自动处理360/0度边界)
        float offset = Mathf.DeltaAngle(climbBaseXRotation, player.transform.eulerAngles.y);
        // 限制偏移范围
        offset = Mathf.Clamp(offset, -xRotationLimit, xRotationLimit);
        // 应用限制后的旋转
        player.transform.rotation = Quaternion.Euler(0, climbBaseXRotation + offset, 0);
    }
    else
    {
        // 正常状态下的水平旋转,重置基准值
        climbBaseXRotation = 0;
        rotation.x += mouseDelta.x * sensitivity;
        rotation.x = Mathf.Repeat(rotation.x, 360f); // 替代手动范围判断,更简洁
        player.transform.rotation = Quaternion.AngleAxis(rotation.x, Vector3.up);
    }

    // 设置相机垂直旋转,避免万向锁
    transform.localRotation = Quaternion.Euler(-rotation.y, 0, 0);
}

关键改进点:

  • 用Mathf.DeltaAngle计算旋转偏移,解决360/0度交界处的跳变问题
  • 基于攀爬触发时的基准旋转限制偏移,避免强制拉到固定角度的突兀感
  • 相机垂直旋转直接绑定欧拉角的Y轴,和玩家水平旋转分离,避免万向锁
  • 用Mathf.Repeat简化0-360度范围处理

补充优化

给WallClimbing添加离开触发器的逻辑,确保攀爬状态能正常关闭:

public void OnTriggerExit(Collider other)
{
    if (other.gameObject.CompareTag("Wall"))
    {
        isClimbingWall = false;
    }
}

同时检查CameraLook脚本中wallClimbing引用是否已在Inspector面板赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:24:53