问题描述
我正在尝试夹紧相机的 X 轴和 Y 轴,我已经设法做到了。但是,当钳位值达到 MAX 阈值时,它将跳回到 MIN 阈值! 知道是什么导致我的代码出现这种情况吗?
private void climbingLookRotation()
{
if (input.mouseX != 0 || input.mouseY != 0f)
{
orientation.rotation *= Quaternion.AngleAxis(input.mouseX,Vector3.up);
orientation.rotation *= Quaternion.AngleAxis(input.mouseY,Vector3.right);
}
var rotX = orientation.eulerAngles.x;
var rotY = orientation.eulerAngles.y;
rotX = Mathf.Clamp(rotX,1,25);
rotY = Mathf.Clamp(rotY,200,355);
orientation.eulerAngles = new Vector3(rotX,rotY,0);
}
任何帮助将不胜感激! 谢谢。
解决方法
您可以将欧拉角围绕中心值重新居中,然后缩小差异:
float centralX = 13f;
float extentX = 12f;
float centralY = 277.5f;
float extentY = 77.5f;
private static float ClampEuler(float val,float center,float extent)
{
return center + Mathf.Clamp((val - center + 360f) % 360f,-extent,extent);
}
private void ClimbingLookRotation()
{
if (input.mouseX != 0 || input.mouseY != 0f)
{
orientation.rotation *= Quaternion.AngleAxis(input.mouseX,Vector3.up);
orientation.rotation *= Quaternion.AngleAxis(input.mouseY,Vector3.right);
}
var rotX = orientation.eulerAngles.x;
var rotY = orientation.eulerAngles.y;
rotX = ClampEuler(rotX,centralX,extentX);
rotY = ClampEuler(rotY,centralY,extentY);
orientation.eulerAngles = new Vector3(rotX,rotY,0);
}
顺便说一下,您可能想要执行 orientation.rotation *= Quaternion.AngleAxis(input.mouseY,orientation.right);
来围绕局部右侧而不是全局右侧旋转。随着时间的推移,围绕全局右侧旋转可能会产生您可能不想要的滚动效果。
我发现了一些效果很好的东西,所以我想我会回答,以防它对任何人有帮助!
public static float ClampAngle(float angle,float min,float max)
{ //Normalises angle value passed in between -180 to 180 to make the angle clampable
angle = NormalizeAngle(angle);
if (angle > 180)
{
angle -= 360;
}
else if (angle < -180)
{
angle += 360;
}
min = NormalizeAngle(min);
if (min > 180)
{
min -= 360;
}
else if (min < -180)
{
min += 360;
}
max = NormalizeAngle(max);
if (max > 180)
{
max -= 360;
}
else if (max < -180)
{
max += 360;
}
return Mathf.Clamp(angle,min,max);
}
public static float NormalizeAngle(float angle)
{ //If the angle is above or below 360 degrees,normalise it
while (angle > 360)
angle -= 360;
while (angle < 0)
angle += 360;
return angle;
}
然后只需在需要限制值的地方调用 ClampAngle 方法,例如:
private void ClimbingLookRotation()
{
if (input.mouseX != 0 || input.mouseY != 0f)
{
orientation.rotation *= Quaternion.AngleAxis(input.mouseX,Vector3.up);
orientation.rotation *= Quaternion.AngleAxis(input.mouseY,Vector3.right);
}
var rotX = orientation.eulerAngles.x;
var rotY = orientation.eulerAngles.y;
rotX = HelperFunctions.ClampAngle(rotX,-10,25); //Here
rotY = HelperFunctions.ClampAngle(rotY,200,340); //And here
orientation.eulerAngles = new Vector3(rotX,0);
}
我在我的相机旋转函数中调用了它来钳制 rotX 和 rotY,这后来被应用于我的方向游戏对象的旋转。
再次感谢 Ruzihm 之前的帮助 :)