【问题标题】:When rotating 2D sprite towards cursor via angularVelocity, it spins at one point当通过 angularVelocity 向光标旋转 2D 精灵时,它会旋转一点
【发布时间】:2017-01-19 19:34:46
【问题描述】:

简介

我在我的 Unity 项目中创建了一个宇宙飞船精灵,我希望它通过角速度向光标旋转,因为我想让我的游戏高度基于物理。

问题

现在我通过 角速度 旋转 sprite 的问题如下:

在 -180° / 180° 旋转时,我的船会旋转,因为虽然我的鼠标的 角度 已经是 180°,而我的船的 旋转 仍然是 -180°,或者反过来。

我试过了

我试图用数学方法解决它,但不太成功,我可以让它以正确的方式旋转,只是慢得多/快得多,我可以修复 180/-180 点,但改为做了两个不同的点。

寻找不同的解决方案,但找不到更合适的解决方案。

代码

所以我有这个旋转代码:

// Use this for initialization
void Start () {
    rb = gameObject.GetComponent<Rigidbody2D>();
}

// Update is called once per frame
void Update () {
    //getting mouse position in world units
    mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

    //getting the angle of the ship -> cursor vector
    angle = Mathf.Atan2(mousePos.y - transform.position.y, mousePos.x - transform.position.x) * Mathf.Rad2Deg;

    //getting the angle between the ship -> cursor and the rigidbody.rotation vector
    diffAngle = angle - (rb.rotation + 90);

    //Increasing angular velocity scaling with the diffAngle
    rb.angularVelocity = diffAngle * Time.deltaTime * PlayerShipStats.Instance.speed * 100f;

提前感谢您的贡献

问题 1 的解决方案

插入此代码使其工作,不会很长时间

if(diffAngle > 180) {
        diffAngle -= 360;
    } else if (diffAngle < -180) {
        diffAngle += 360;
    }

问题2和问题2的解决方案

新的问题是: rigidbody.rotation 可以超出它的边界,它可以旋转超过 360 度。

这段代码修复了这个错误:

if(rb.rotation + 90 >= 180) {
            rb.rotation = -270;
        } else if (rb.rotation + 90 <= -180) {
            rb.rotation =  90;
        }

完美的代码

void AimAtTarget(Vector2 target, float aimSpeed) {

    //getting the angle of the this -> target vector
    float targetAngle = Mathf.Atan2(target.y - transform.position.y, target.x - transform.position.x) * Mathf.Rad2Deg;

    if (rb.rotation + 90 >= 180) {
        rb.rotation = -270;
    } else if (rb.rotation + 90 <= -180) {
        rb.rotation = 90;
    }

    //getting the angle between the this -> target and the rigidbody.rotation vector
    float diffAngle = targetAngle - (rb.rotation - 90);

    if (diffAngle > 180) {
        diffAngle -= 360;
    } else if (diffAngle < -180) {
        diffAngle += 360;
    }

    //Increasing angular velocity scaling with the diffAngle
    rb.angularVelocity = diffAngle * Time.deltaTime * aimSpeed * 100;
}

【问题讨论】:

  • 您应该标准化角度差,使其始终在 -180°..180° 范围内。即if(diffAngle&gt;180) diffAngle -=360; 等。顺便问一下,Mathf.Atan2 是返回度数还是弧度?
  • @LutzL 我实际上使用 Mathf.Clamp 来限制转动速度,但我想让我的代码在这篇文章中不那么密集。可悲的是,即使我检测到 diffAngle 超过 180,我也无法使旋转平滑。有一侧会很糟糕,因为您的旋转灵敏度不同。 Mathf.Atan2 返回弧度并处理切线异常。
  • 您确定rb.rotation 也是弧度吗?这似乎与使用的90 校正相矛盾,因为我认为这意味着一个直角。 -- 我建议的不是切割,而是2*pi resp 360° 的修正,它在单位圆上给出相同的位置,但角度不同。必须通过添加一个完整的圆圈来对 diffAngle&lt;-180 进行类似的更正。
  • Rb.rotation 返回度数,但此脚本运行良好,直到您到达转折点。
  • 抱歉,我查看了行尾的答案,您确实拥有Rad2Deg 转换因子。所以只剩下居中问题,这在答案中进行了讨论,也许还讨论了您用于角度动力学的哪种方程(如果dt 是一个指示,则为微分)。

标签: math unity3d unity5 game-physics unity3d-2dtools


【解决方案1】:

我在这里看到两个问题:

问题 1

angle 总是介于 -180 和 180 之间,而 rb.rotation 介于 0 和 360 之间。因此,您使用两种不同的符号比较角度。第一步是让两个角度都返回 -180 到 180 或 0 到 360。我选择执行以下操作,将两个角度置于 -180 到 180 之间:

//getting the angle of the ship -> cursor vector
float targetAngle = Mathf.Atan2(
    mousePos.y - transform.position.y, 
    mousePos.x - transform.position.x) * Mathf.Rad2Deg;

//get the current angle of the ship
float sourceAngle = Mathf.Atan2(
    this.transform.up.y, 
    this.transform.up.x) * Mathf.Rad2Deg;

问题 2

如果您解决了问题 1 并尝试了您的应用程序,您会注意到船有时会以错误的方式旋转,尽管它最终会到达目标。问题是diffAngle 有时会给出大于+180 度(或小于-180)的结果。当这种情况发生时,我们实际上希望船向另一个方向旋转。该代码如下所示:

//getting the angle between the ship -> cursor and the rigidbody.rotation vector
float diffAngle = targetAngle - sourceAngle;

//use the smaller of the two angles to ensure we always turn the correct way
if (Mathf.Abs(diffAngle) > 180f)
{
    diffAngle = sourceAngle - targetAngle;
}

我做了一个简单的 Unity 来验证它的工作原理。我能够顺利地向任一方向旋转我的船。

如果您还没有处理的话,您可能需要处理的一件事是在飞船面向光标时适当地停止它的旋转。在我的测试中,我注意到船在到达目标时会轻微抖动,因为它会(非常)略微超过光标在一个方向然后另一个方向的角度。 PlayerShipStats.Instance.speed 的值越大,这种效果可能越明显。

【讨论】:

  • 其实我没有问题 1,angle(rb.rotation - 90) 在同一点返回了相同的角度(在{-180, 180} 间隔上)。但是您对我的“问题2”的回答应该有效,我会尽快尝试。谢谢。
  • 我更新了我的问题以包含答案,最终你和@LutzL 想通了,我只是稍微改变了一下以适应上下文。完全没有抖动。谢谢各位
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 2014-10-04
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 1970-01-01
  • 2015-06-02
相关资源
最近更新 更多