当通过 angularVelocity 将 2D 精灵旋转到光标时,它会在一点旋转
When rotating 2D sprite towards cursor via angularVelocity, it spins at one point
简介
我在我的 Unity 项目中创建了一个宇宙飞船精灵,我希望它通过 angular 速度向光标旋转,因为我想让我的游戏非常基于物理。
问题
现在我通过 angular 速度 旋转 sprite 的问题如下:
在 -180° / 180° 旋转时,我的船旋转,因为虽然我的鼠标 angle 已经是 180°,而我的船 rotation 仍然是 -180°,反之亦然。
我试过了
我试图用数学方法解决它,不太成功,我可以让它以正确的方式旋转 slower/faster,我可以修复 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
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
的值越大,这种效果可能越明显。
简介
我在我的 Unity 项目中创建了一个宇宙飞船精灵,我希望它通过 angular 速度向光标旋转,因为我想让我的游戏非常基于物理。
问题
现在我通过 angular 速度 旋转 sprite 的问题如下:
在 -180° / 180° 旋转时,我的船旋转,因为虽然我的鼠标 angle 已经是 180°,而我的船 rotation 仍然是 -180°,反之亦然。
我试过了
我试图用数学方法解决它,不太成功,我可以让它以正确的方式旋转 slower/faster,我可以修复 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
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
的值越大,这种效果可能越明显。