You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity 2D游戏C#脚本问题:潜艇火炮限幅朝向鼠标失效

解决你的Unity 2D火炮朝向鼠标问题

我仔细看了你的代码和问题描述,发现几个关键问题导致火炮没法正确朝向鼠标,咱们一步步来修正:

问题根源

  1. 坐标系错误:你用transform.localPosition计算方向,但火炮是炮塔的子物体,鼠标转成世界坐标后,应该用火炮的世界位置(或者转换到炮塔的局部坐标系)来计算方向,否则会因为父子物体的层级坐标系混乱,导致方向计算错误。
  2. 角度绝对值错误:你用了Mathf.Abs(angle),把所有角度都转成了正值,这就意味着不管鼠标在火炮的左边还是右边,角度都是正的,自然没法正确朝向鼠标位置。
  3. 角度限制逻辑顺序错了:应该先算出正确的目标朝向角度,再对这个角度做范围限制,而不是先取绝对值再限制。

修正后的代码

void Update()
{
    // 获取鼠标的世界坐标,2D场景下强制z值为0,避免Camera带来的位置偏差
    Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    mouseWorldPos.z = 0f;

    // 获取炮塔父物体,计算鼠标在炮塔局部坐标系下的位置
    Transform turretTransform = transform.parent;
    Vector3 mouseLocalToTurret = turretTransform.InverseTransformPoint(mouseWorldPos);

    // 计算相对于炮塔的方向向量
    Vector2 localDirection = new Vector2(mouseLocalToTurret.x, mouseLocalToTurret.y);

    // 计算目标旋转角度(转成角度值)
    float targetAngle = Mathf.Atan2(localDirection.y, localDirection.x) * Mathf.Rad2Deg;

    // 将角度限制在你需要的范围内(这里保留你原来的40-140,可根据需求调整)
    float clampedAngle = Mathf.Clamp(targetAngle, 40f, 140f);

    // 应用局部旋转到火炮上
    transform.localRotation = Quaternion.Euler(0, 0, clampedAngle);
}

关键修改说明

  • 坐标系转换:通过turretTransform.InverseTransformPoint把鼠标世界坐标转成炮塔的局部坐标,这样计算的角度是相对于炮塔的,完全符合localRotation的使用场景(因为火炮是炮塔的子物体)。
  • 保留角度正负:去掉了Mathf.Abs,让角度能正确反映鼠标在炮塔的左侧或右侧,火炮就能准确朝向鼠标。
  • 简洁的角度限制:用Mathf.Clamp替代嵌套的Mathf.Min/Max,逻辑更清晰,也更易维护。

如果你的角度限制范围需要调整(比如允许火炮向左旋转到-140°之类的),只需要修改Mathf.Clamp的后两个参数就行。另外确保你的Camera是正交相机(2D游戏常用),这样ScreenToWorldPoint的计算才会准确。

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

火山引擎 最新活动