对象未按从 Atan2 到四元数的正确方向旋转
Object does not rotate in the correct direction from Atan2 to Quaternion
我正在尝试在其 z 轴上旋转一个对象,给定一个我用 Atan2 函数以一定角度计算的点。然后我创建一个四元数以将其输入到对象的旋转中。然而,它并没有按照假定的正确方向旋转。如果我绘制 Atan2 函数给出的角度图,我会想象一个顺时针角度系统,但如果我绘制应该使我的对象在正确方向上呈现的角度,我会想象一个逆时针系统。使用 Atan2 函数接收的值作为键创建字典的解决方案,它们的值是对象将旋转正确方向的角度。但我仍然不明白发生了什么。我希望有人能帮助我理解它,因为没有比解决但不知道发生了什么更糟糕的解决方案。
public class ArrowMovement : MonoBehaviour
{
public Vector2Variable currentPlayerDirection;
public Vector3Variable currentPlayerPosition;
public InputAxis inputAxis;
private float anglePassed;
private Dictionary<float, float> realAngles = new Dictionary<float, float>();
void Awake()
{
realAngles.Add(-135, -135);
realAngles.Add(-90, 180);
realAngles.Add(-45, 135);
realAngles.Add(0, 90);
realAngles.Add(45, 45);
realAngles.Add(90, 0);
realAngles.Add(135, -45);
realAngles.Add(180, -90);
}
void Update()
{
Vector3 offsetVector = new Vector3(0.2f, 0.05f, 0);
transform.position = currentPlayerPosition.Value;
// Rotation
float angle = Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.Euler(0, 0, realAngles[angle]);
transform.rotation = rotation;
}
}
创建字典不是最好的方法,因为它没有考虑您设置的字典之间的角度,因此要从一个图表转换为另一个图表,我会创建一个如下所示的函数:
float ChangeAngleDiagram(float angle) {
return -(angle + 90f)+180;
}
首先,你应该知道inputAxis
是什么。
我可以从你的图表中猜到你期望 inputAxis.verticall == 0
的角度必须为 0。让我们看一下 Mathf.Athan2(y,x)
- it is equivalent to arctan(y/x)
,因此只有当 y
为零时结果才会为零。但是,在您的代码中,Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall)
会在 inputAxis.horizontal == 0
时给出 0 - 它是垂直方向(您的第一个图表)。
第二个问题-旋转方向错误。当其中一个输入轴反转时,可能会发生这种情况。可能 inputAxis
是在相对于您的对象的不同坐标系中测量的,即您的对象的 Z
是您的 inputAxis
的 -Z
。反正inputAxis.verticall
可以反
float angle = Mathf.Atan2(inputAxis.horizontal, -inputAxis.verticall) * Mathf.Rad2Deg;
此外,您应该避免使用 "creating a dictionary" 或类似方法解决简单的几何问题。即使您不知道 inputAxis
是如何工作的并且结果是错误的 - 分两步来修复它: 1. 固定旋转方向 - 只需反转角度 Quaternion.Euler(0, 0, -angle)
; 2.固定零位-添加一些静态旋转。在你的情况下是 90 度 Quaternion.Euler(0, 0, 90 - angle)
。并且是解决问题的第二种方法。
我正在尝试在其 z 轴上旋转一个对象,给定一个我用 Atan2 函数以一定角度计算的点。然后我创建一个四元数以将其输入到对象的旋转中。然而,它并没有按照假定的正确方向旋转。如果我绘制 Atan2 函数给出的角度图,我会想象一个顺时针角度系统,但如果我绘制应该使我的对象在正确方向上呈现的角度,我会想象一个逆时针系统。使用 Atan2 函数接收的值作为键创建字典的解决方案,它们的值是对象将旋转正确方向的角度。但我仍然不明白发生了什么。我希望有人能帮助我理解它,因为没有比解决但不知道发生了什么更糟糕的解决方案。
public class ArrowMovement : MonoBehaviour
{
public Vector2Variable currentPlayerDirection;
public Vector3Variable currentPlayerPosition;
public InputAxis inputAxis;
private float anglePassed;
private Dictionary<float, float> realAngles = new Dictionary<float, float>();
void Awake()
{
realAngles.Add(-135, -135);
realAngles.Add(-90, 180);
realAngles.Add(-45, 135);
realAngles.Add(0, 90);
realAngles.Add(45, 45);
realAngles.Add(90, 0);
realAngles.Add(135, -45);
realAngles.Add(180, -90);
}
void Update()
{
Vector3 offsetVector = new Vector3(0.2f, 0.05f, 0);
transform.position = currentPlayerPosition.Value;
// Rotation
float angle = Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.Euler(0, 0, realAngles[angle]);
transform.rotation = rotation;
}
}
创建字典不是最好的方法,因为它没有考虑您设置的字典之间的角度,因此要从一个图表转换为另一个图表,我会创建一个如下所示的函数:
float ChangeAngleDiagram(float angle) {
return -(angle + 90f)+180;
}
首先,你应该知道inputAxis
是什么。
我可以从你的图表中猜到你期望 inputAxis.verticall == 0
的角度必须为 0。让我们看一下 Mathf.Athan2(y,x)
- it is equivalent to arctan(y/x)
,因此只有当 y
为零时结果才会为零。但是,在您的代码中,Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall)
会在 inputAxis.horizontal == 0
时给出 0 - 它是垂直方向(您的第一个图表)。
第二个问题-旋转方向错误。当其中一个输入轴反转时,可能会发生这种情况。可能 inputAxis
是在相对于您的对象的不同坐标系中测量的,即您的对象的 Z
是您的 inputAxis
的 -Z
。反正inputAxis.verticall
可以反
float angle = Mathf.Atan2(inputAxis.horizontal, -inputAxis.verticall) * Mathf.Rad2Deg;
此外,您应该避免使用 "creating a dictionary" 或类似方法解决简单的几何问题。即使您不知道 inputAxis
是如何工作的并且结果是错误的 - 分两步来修复它: 1. 固定旋转方向 - 只需反转角度 Quaternion.Euler(0, 0, -angle)
; 2.固定零位-添加一些静态旋转。在你的情况下是 90 度 Quaternion.Euler(0, 0, 90 - angle)
。并且是解决问题的第二种方法。