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