通过angularVelocity将2D精灵旋转到光标时,它会在一个点上旋转

时间:2017-01-19 19:34:47

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

简介

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

问题

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

在-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;
}

1 个答案:

答案 0 :(得分:0)

我在这里看到两个问题:

问题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的值越大,这种效应可能越明显。