防止逆时针旋转
Prevent counterclockwise rotation
所以我有一个附有把手的物体,玩家应该旋转这个把手。为此,我获取了控制器模拟摇杆的水平轴和垂直轴,并将这些值转换为度数,然后我用它来旋转对象。
问题是我似乎无法完全排除逆时针旋转手柄的可能性,因为玩家只能顺时针旋转它。发生的情况是,当我尝试逆时针旋转时,每隔几帧它就会检测到顺时针旋转,执行我相应的代码,即使我一直在逆时针旋转。
我用来确定旋转方向的原则是通过比较上一帧的输入角度和当前输入角度来完成的,例如:
// Variant 1:
var inputAngle = Mathf.Atan2(x, y) * Mathf.Rad2Deg;
float angleDifference = inputAngle - previousAngle;
if (angleDifference > 180f) angleDifference -= 360f;
if (angleDifference < -180f) angleDifference += 360f;
if (Mathf.Sign(angleDifference).Equals(-1))
{
// Counterclockwise rotation
}
else
{
// Clockwise rotation
}
// ...
previousAngle = inputAngle;
在另一次尝试中,我尝试通过简单地检查我当前的角度是否大于我之前的角度来进行比较,同时将输入转换为 0° 到 360° 的范围,并处理返回到的溢出从 360° 到 0°,也不能始终如一地工作。
所以我试图查看在这种错误情况下给出的值,但这只是告诉我这些值并不像我预期的那样,因为当前角度应该小于前一个角度逆时针旋转时,在那些情况下,我不知道为什么或如何防止它?
所以我想最后我的问题是如何通过读取控制器的模拟摇杆输入来始终阻止玩家逆时针旋转。
我会使用 Vector3.SignedAngle 来获得围绕前进轴的到-从角度。那么如果角度为负,就是顺时针;正为逆时针:
Vector3 previousPos;
Vector3 GetPos()
{
/* return current controller position, between (-1,-1,0) and (1,1,0) */
}
void Awake() { previousPos = previousPos; }
void Update()
{
Vector3 curPos = GetPos();
float deltaAngle = Vector3.SignedAngle(previousPos, curPos, Vector3.foward);
// If you want to clamp the speed
// float maxSpeed = 180f; // max rotational speed = 180 degrees per second
// deltaAngle = Mathf.Clamp(deltaAngle/Time.deltaTime, -maxSpeed, maxSpeed)
// * Time.deltaTime;
bool isClockwise = deltaAngle < 0;
bool isCounterClockwise = deltaAngle > 0;
if (isClockwise)
{
// do stuff when motion is clockwise
}
else if (isCounterClockwise)
{
// do stuff when motion is counter clockwise
}
else
{
// do stuff when no rotational motion occurs
}
previousPos = curPos;
}
所以我有一个附有把手的物体,玩家应该旋转这个把手。为此,我获取了控制器模拟摇杆的水平轴和垂直轴,并将这些值转换为度数,然后我用它来旋转对象。
问题是我似乎无法完全排除逆时针旋转手柄的可能性,因为玩家只能顺时针旋转它。发生的情况是,当我尝试逆时针旋转时,每隔几帧它就会检测到顺时针旋转,执行我相应的代码,即使我一直在逆时针旋转。
我用来确定旋转方向的原则是通过比较上一帧的输入角度和当前输入角度来完成的,例如:
// Variant 1:
var inputAngle = Mathf.Atan2(x, y) * Mathf.Rad2Deg;
float angleDifference = inputAngle - previousAngle;
if (angleDifference > 180f) angleDifference -= 360f;
if (angleDifference < -180f) angleDifference += 360f;
if (Mathf.Sign(angleDifference).Equals(-1))
{
// Counterclockwise rotation
}
else
{
// Clockwise rotation
}
// ...
previousAngle = inputAngle;
在另一次尝试中,我尝试通过简单地检查我当前的角度是否大于我之前的角度来进行比较,同时将输入转换为 0° 到 360° 的范围,并处理返回到的溢出从 360° 到 0°,也不能始终如一地工作。
所以我试图查看在这种错误情况下给出的值,但这只是告诉我这些值并不像我预期的那样,因为当前角度应该小于前一个角度逆时针旋转时,在那些情况下,我不知道为什么或如何防止它?
所以我想最后我的问题是如何通过读取控制器的模拟摇杆输入来始终阻止玩家逆时针旋转。
我会使用 Vector3.SignedAngle 来获得围绕前进轴的到-从角度。那么如果角度为负,就是顺时针;正为逆时针:
Vector3 previousPos;
Vector3 GetPos()
{
/* return current controller position, between (-1,-1,0) and (1,1,0) */
}
void Awake() { previousPos = previousPos; }
void Update()
{
Vector3 curPos = GetPos();
float deltaAngle = Vector3.SignedAngle(previousPos, curPos, Vector3.foward);
// If you want to clamp the speed
// float maxSpeed = 180f; // max rotational speed = 180 degrees per second
// deltaAngle = Mathf.Clamp(deltaAngle/Time.deltaTime, -maxSpeed, maxSpeed)
// * Time.deltaTime;
bool isClockwise = deltaAngle < 0;
bool isCounterClockwise = deltaAngle > 0;
if (isClockwise)
{
// do stuff when motion is clockwise
}
else if (isCounterClockwise)
{
// do stuff when motion is counter clockwise
}
else
{
// do stuff when no rotational motion occurs
}
previousPos = curPos;
}