I cobbled this code together from this and help on the IRC.
using UnityEngine;
using System.Collections;
public class RotationClamp : MonoBehaviour
{
public float xMinLimit = -20f;
public float xMaxLimit = 80f;
void Update()
{
Vector3 angles = transform.eulerAngles;
angles.x = ClampAngle(angles.x, xMinLimit, xMaxLimit);
transform.eulerAngles = angles;
transform.Rotate(Vector3.right * -0.1f);
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
It works when I rotate toward the maximum limit. But when I rotate it beyond the minimum limit it jumps past it automatically, then continues to rotate and jumps again. Anybody know why that happens, and how I can fix it?
Its that whole rotations can only be 0-360 degree thing…
Without using your static helper…
if(angles.x > 180 angles.x < (360 + xMinLimit))
angles.x = 360 + xMinLimit;
else if(angles.x > xMaxLimit)
angles.x = xMaxLimit;
OK, you will notice if you track x that it travels from 80 to 0 then flips back to 80. This means that when you pull the euler, it’s rotation is stuck to 0 to 360. What you would need to do is change some of the criteria in your ClampAngle function…
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -180F)
angle += 360F;
if (angle > 180F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
This means that it will clamp from -180 to 180, instead of letting the euler rule with 0-360.
Alternatively, you can leave the ClampAngle function alone and change this:
void Update()
{
angles = transform.eulerAngles;
angles.x -= 20.0f * Time.deltaTime;
angles.x = ClampAngle(angles.x, xMinLimit, xMaxLimit);
transform.eulerAngles = angles;
}
This would force a variable to keep track of the value of the angle and not let the internal euler twist it up for you. (this is the way the MouseLook and MouseOrbits work.)
Thanks guys!
Now if I want to make this a rigidbody game object, I should just move the code from Update() to FixedUpdate()?
It is not advised to use this on a rigidbody. They move according to the laws of Physx (omg what a pun)
I would specifically use this for something that is user or mathematically controlled.
Well since I’m making a physics game, I suppose I should try to re-implement this clamping with physics. Thanks.
The thing you would have to do is to halt the angularVelocity for the clamped direction. you would need that rather than a mathematical clamp.
This may be possible in much the same way. Compare the eulerx from -180 to 180 against the angularVelocity Inverse Transformed by its direction. So if it goes above or below the values, change the angular velocity on that value to zero, set the angle and then reapply the angularVelocity back to it… transformed back of course.
Thanks, I’ll try that when I’ve learned more about physics and stuff. Or maybe I should rethink using physics all together.
Since my game would be breaking the laws of physics, why use it?