英文:
How do I clamp horizontal axis rotation?
问题
// WallClimbing script
public void OnTriggerEnter(Collider other)
{
if (col.gameObject.tag == "Wall")
{
isClimbingWall = true;
}
}
// CameraLook script
Vector2 mouseDelta = new Vector2(Input.GetAxis(xAxis), Input.GetAxis(yAxis));
rotation.x += mouseDelta.x * sensitivity;
//Keep rotation in the range 0-360.
if (rotation.x < 0) rotation.x += 360f;
if (rotation.x > 360f) rotation.x -= 360f;
rotation.y += mouseDelta.y * sensitivity;
rotation.y = Mathf.Clamp(rotation.y, -yRotationLimit, yRotationLimit); // vertical clamp
if (wallClimbing.isClimbingWall)
{
//horizontal clamp
rotation.x = Mathf.Clamp(rotation.x, -xRotationLimit, xRotationLimit); // xRotLimit 35f
}
var xQuaternion = Quaternion.AngleAxis(rotation.x, Vector3.up);
var yQuaternion = Quaternion.AngleAxis(rotation.y, Vector3.left);
transform.localRotation = yQuaternion;
player.transform.rotation = xQuaternion;
However what happens is, no matter which angle the wall is positioned, when I enter the trigger my player/camera rotation will "snap" forward.
<details>
<summary>英文:</summary>
I have two scripts for this and how it is supposed to work is, if I enter a trigger, my `isClimbingWall` bool turns true which performs specific movements inside of my WallClimbing script. I also use that bool in my second script CameraLook in order to clamp my x-axis rotation.
// WallClimbing script
public void OnTriggerEnter(Collider other)
{
if (col.gameObject.tag == "Wall")
{
isClimbingWall = true;
}
}
To get the clamp to work, I just add a quick if statement in the middle of my code so that if I am climbing, clamp x-axis rotation but it does not seem to work. I replaced `eulerAngles` with `AngleAxis` but I still get gimbal lock.
// CameraLook script
Vector2 mouseDelta = new Vector2(Input.GetAxis(xAxis), Input.GetAxis(yAxis));
rotation.x += mouseDelta.x * sensitivity;
//Keep rotation in the range 0-360.
if (rotation.x < 0) rotation.x += 360f;
if (rotation.x > 360f) rotation.x -= 360f;
rotation.y += mouseDelta.y * sensitivity;
rotation.y = Mathf.Clamp(rotation.y, -yRotationLimit, yRotationLimit); // vertical clamp
if (wallClimbing.isClimbingWall)
{
//horizontal clamp
rotation.x = Mathf.Clamp(rotation.x, -xRotationLimit, xRotationLimit); // xRotLimit 35f
}
var xQuaternion = Quaternion.AngleAxis(rotation.x, Vector3.up);
var yQuaternion = Quaternion.AngleAxis(rotation.y, Vector3.left);
transform.localRotation = yQuaternion;
player.transform.rotation = xQuaternion;
However what happens is, no matter which angle the wall is positioned, when I enter the trigger my player/camera rotation will "snap" forward.
</details>
# 答案1
**得分**: 1
将旋转限制在+/-35度范围内,通过仅使用`Clamp`应用于270度,将得到+35度,但应该得到-35度,因为270度与-90度相同。
因此,创建一个将角度标准化在-180到+180度之间的函数:
``` c#
public static float NormalizeAngle(float angle)
{
angle = (angle + 180) % 360;
if (angle < 0) {
angle += 360;
}
return angle - 180;
}
然后您可以编写:
rotation.x =
Mathf.Clamp(NormalizeAngle(rotation.x), -xRotationLimit, xRotationLimit);
英文:
Limiting the rotation to +/-35 degrees will yield +35 for 270 degrees by applying only Clamp
, but should yield -35, since 270 is the same as -90.
Therefore, create a function which normalizes the angle between -180 and +180 degrees:
public static float NormalizeAngle(float angle)
{
angle = (angle + 180) % 360;
if (angle < 0) {
angle += 360;
}
return angle - 180;
}
Then you can write:
rotation.x =
Mathf.Clamp(NormalizeAngle(rotation.x), -xRotationLimit, xRotationLimit);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论