You need to enable JavaScript to run this app. Unity 2D 适配父级旋转、带角度限制的硬点鼠标瞄准象限异常
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2D 适配父级旋转、带角度限制的硬点鼠标瞄准象限异常

硬点瞄准逻辑异常排查与修正

异常根因

当前逻辑的核心遗漏是所有旋转角度属于环形循环数值域,不存在绝对的线性大小比较关系。

  • 原代码计算minAngle、maxAngle时没有对结果做0~360范围的归一化,会出现大于360的计算值(比如槽位z轴旋转270°时,计算得到的maxAngle为380°)
  • 当允许旋转的区间跨过0°/360°的循环边界时(例如合法范围实际为340°~20°),原有的线性判断angle < minAngle则设为minAngle会完全失效:
    • 此时落在合法范围内的角度(比如0°、10°这类靠近0度的鼠标瞄准值),会因为数值上小于340°的minAngle,被强制钳制到340°的边界值
    • 这个失效的区间正好覆盖屏幕右上象限对应的角度范围,和实际观察到的90度区间逻辑混乱、其余270度范围运行正常的现象完全匹配

逻辑修正要点

  • 统一所有角度值的计算基准,将任意范围的输入角度全部归一化到0360的环形域内,替代原有仅支持-180°180°转换的OneEightyToThreeSixty()方法
  • 提前判断当前允许的旋转区间是否跨过0°边界:当归一化后的minAngle值大于maxAngle值时,说明区间是绕0点环绕的,不能用常规的线性大小判断
  • 对跨边界的区间调整合法性判断:合法角度范围为「角度 >= minAngle 或者 角度 <= maxAngle」,而非原来的「角度在min和max之间」
  • 角度钳制时采用环形距离计算,判断当前瞄准角度离哪个区间边界更近,再钳制到对应值,避免直接数值大小比较带来的错误

参考修正代码片段

public void AimAtMouse()
{
    Vector3 dir = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
    angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

    // 计算允许的角度范围
    minAngle = (transform.eulerAngles.z - 20) + 90f;
    maxAngle = (transform.eulerAngles.z + 20) + 90f;

    // 所有角度统一归一到0~360范围
    angle = NormalizeAngle(angle);
    minAngle = NormalizeAngle(minAngle);
    maxAngle = NormalizeAngle(maxAngle);

    // 判断是否为跨0度的环绕区间
    bool isWrappedRange = minAngle > maxAngle;
    bool isLegalAngle;

    if (isWrappedRange)
    {
        isLegalAngle = angle >= minAngle || angle <= maxAngle;
    }
    else
    {
        isLegalAngle = angle >= minAngle && angle <= maxAngle;
    }

    // 角度不在合法范围时,钳制到最近的边界
    if (!isLegalAngle)
    {
        float distToMin = Mathf.DeltaAngle(angle, minAngle);
        float distToMax = Mathf.DeltaAngle(angle, maxAngle);
        angle = Mathf.Abs(distToMin) < Mathf.Abs(distToMax) ? minAngle : maxAngle;
    }

    hardpoint.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}

// 全角度范围归一方法,替代原有的180-360转换逻辑
public float NormalizeAngle(float inputAngle)
{
    inputAngle = Mathf.Repeat(inputAngle, 360f);
    return inputAngle < 0 ? inputAngle + 360f : inputAngle;
}

补充:原OneEightyToThreeSixty()方法仅覆盖-180°~180°输入值的转换逻辑,无法处理minAngle、maxAngle计算过程中可能出现的超360°的越界值,这也是触发异常的隐性原因。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.10 03:45:03