如何正确夹持360度重叠?
How to properly clamp 360 degrees overlap?
我有一个相机脚本,如果我的角色在旋转,相机也会旋转。然而,相机也可以通过鼠标指针旋转。这种运动受到一组特定的给定度数的限制,比如 30 (maximumX)。所以鼠标控制的相机移动范围应该在0到60之间,相当于-30到30度。
如果角色旋转整整 360 度,则 maxX 值与 360 度重叠,必须返回到 0。而最小值可能保持在 300 左右。这会造成相机 "snap" 和没有正确保留其之前的旋转。
var newMaxX = ClampAngle(_target.localEulerAngles.y + maximumX, -360, 360);
var newMinX = ClampAngle(_target.localEulerAngles.y - maximumX, -360, 360);
if(newMinX > newMaxX)
{
var tmp = newMaxX;
newMaxX = newMinX;
newMinX = tmp;
}
if (axes == RotationAxes.MouseXAndY) {
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationX = ClampAngle (rotationX, newMinX, newMaxX);
rotationY = ClampAngle (rotationY, minimumY, maximumY);
var xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
var yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
cameraTransform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationX = ClampAngle (rotationX, newMinX, newMaxX);
xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
cameraTransform.localRotation = originalRotation * xQuaternion;
}
else
{
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = ClampAngle (rotationY, minimumY, maximumY);
yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
cameraTransform.localRotation = originalRotation * yQuaternion;
}
这是 ClampAngle 函数:
static function ClampAngle (angle : float, min : float, max : float) : float
{
if (angle < -360.0)
angle += 360.0;
if (angle > 360.0)
angle -= 360.0;
return Mathf.Clamp (angle, min, max);
}
有什么建议吗?
我发现的问题是使用:
_target.localEulerAngles.y
作为基地。这是因为 localEulerAngels 在 运行 时只能从 0 到 360。在编辑器中,它没有被限制。 运行时,钳位。这会极大地改变事情,因为最初在旋转 0,如果你向左移动,它会循环到 360。我把它当作它会去 -1。因此,认为我的数学错误或者我没有正确夹紧。
夹紧不会做任何事情,因为它不会注意到任何关于 0 变成 360 的事情。
因此,我决定将其视为 -180 到 180。
var eulerTargetY = _target.localEulerAngles.y;
var newMaxX = 0;
var newMinX = 0;
if(eulerTargetY > 180)
{
var adjustedEuler = eulerTargetY - 360;
newMaxX = adjustedEuler + m_rangeX;
newMinX = adjustedEuler - m_rangeX;
}
else
{
newMaxX = eulerTargetY + m_rangeX;
newMinX = eulerTargetY - m_rangeX;
}
var xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
var yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = ClampAngle (rotationY, minimumY, maximumY);
rotationX = ClampAngle (rotationX, newMinX, newMaxX);
if (axes == RotationAxes.MouseXAndY) {
cameraTransform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
cameraTransform.localRotation = originalRotation * xQuaternion;
}
else
{
cameraTransform.localRotation = originalRotation * yQuaternion;
}
为清楚起见,我将 maximumX 设为 m_rangeX,因为之前我将它作为 2 个独立的单元使用,而目前我同时使用 30 个。所以现在,相机可以正确扫描玩家将鼠标指向 _target.localEulerAngles.y - 30 和 _target.localEulerAngles.y + 30 之间的圆形重叠区域。
我有一个相机脚本,如果我的角色在旋转,相机也会旋转。然而,相机也可以通过鼠标指针旋转。这种运动受到一组特定的给定度数的限制,比如 30 (maximumX)。所以鼠标控制的相机移动范围应该在0到60之间,相当于-30到30度。
如果角色旋转整整 360 度,则 maxX 值与 360 度重叠,必须返回到 0。而最小值可能保持在 300 左右。这会造成相机 "snap" 和没有正确保留其之前的旋转。
var newMaxX = ClampAngle(_target.localEulerAngles.y + maximumX, -360, 360);
var newMinX = ClampAngle(_target.localEulerAngles.y - maximumX, -360, 360);
if(newMinX > newMaxX)
{
var tmp = newMaxX;
newMaxX = newMinX;
newMinX = tmp;
}
if (axes == RotationAxes.MouseXAndY) {
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationX = ClampAngle (rotationX, newMinX, newMaxX);
rotationY = ClampAngle (rotationY, minimumY, maximumY);
var xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
var yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
cameraTransform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationX = ClampAngle (rotationX, newMinX, newMaxX);
xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
cameraTransform.localRotation = originalRotation * xQuaternion;
}
else
{
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = ClampAngle (rotationY, minimumY, maximumY);
yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
cameraTransform.localRotation = originalRotation * yQuaternion;
}
这是 ClampAngle 函数:
static function ClampAngle (angle : float, min : float, max : float) : float
{
if (angle < -360.0)
angle += 360.0;
if (angle > 360.0)
angle -= 360.0;
return Mathf.Clamp (angle, min, max);
}
有什么建议吗?
我发现的问题是使用:
_target.localEulerAngles.y
作为基地。这是因为 localEulerAngels 在 运行 时只能从 0 到 360。在编辑器中,它没有被限制。 运行时,钳位。这会极大地改变事情,因为最初在旋转 0,如果你向左移动,它会循环到 360。我把它当作它会去 -1。因此,认为我的数学错误或者我没有正确夹紧。
夹紧不会做任何事情,因为它不会注意到任何关于 0 变成 360 的事情。
因此,我决定将其视为 -180 到 180。
var eulerTargetY = _target.localEulerAngles.y;
var newMaxX = 0;
var newMinX = 0;
if(eulerTargetY > 180)
{
var adjustedEuler = eulerTargetY - 360;
newMaxX = adjustedEuler + m_rangeX;
newMinX = adjustedEuler - m_rangeX;
}
else
{
newMaxX = eulerTargetY + m_rangeX;
newMinX = eulerTargetY - m_rangeX;
}
var xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
var yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = ClampAngle (rotationY, minimumY, maximumY);
rotationX = ClampAngle (rotationX, newMinX, newMaxX);
if (axes == RotationAxes.MouseXAndY) {
cameraTransform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
cameraTransform.localRotation = originalRotation * xQuaternion;
}
else
{
cameraTransform.localRotation = originalRotation * yQuaternion;
}
为清楚起见,我将 maximumX 设为 m_rangeX,因为之前我将它作为 2 个独立的单元使用,而目前我同时使用 30 个。所以现在,相机可以正确扫描玩家将鼠标指向 _target.localEulerAngles.y - 30 和 _target.localEulerAngles.y + 30 之间的圆形重叠区域。