- Home /
How to limit the rotation of transform.Rotate
i try to make the rotation of the object with a limitation.currently the object rotation is 360 degrees, for both up down and left right. that object rotate by swipe left right or up down. the limitation that i want is for up down rotation, i want the object just rotate in 90 degrees. thank you for help
public float turnSpeed;
private Vector2 startPos;
void OnMouseDrag(){
float rotationX = Input.GetAxis ("Mouse X");
float rotationY = Input.GetAxis ("Mouse Y");
//left and right
if (Mathf.Abs (rotationX) > Mathf.Abs (rotationY)) {
if (rotationX > 0)
transform.Rotate (Vector3.up, -turnSpeed * Time.deltaTime);
else
transform.Rotate (Vector3.up, turnSpeed * Time.deltaTime);
}
//up and down
if (Mathf.Abs (rotationX) < Mathf.Abs (rotationY)){
if(rotationY < 0){
transform.Rotate(Vector3.right, -turnSpeed * Time.deltaTime);
}
else {
transform.Rotate(Vector3.right, turnSpeed * Time.deltaTime);
}
}
}
Answer by PlatformSix · Jun 11, 2015 at 01:50 PM
If it's just rotating around one axis, maybe store the rotation as a Vector3, then clamp it and re-apply just before you close that function.
float minRotation = -45;
float maxRotation = 45;
Vector3 currentRotation = transform.localRotation.eulerAngles;
currentRotation.y = Mathf.Clamp(currentRotation.y, minRotation, maxRotation);
transform.localRotation = Quaternion.Euler (currentRotation);
thank you for your suggestion, but actually i'm not sure where should i put this?
currentRotation.y = $$anonymous$$athf.Clamp(currentRotation.y, $$anonymous$$Rotation, maxRotation);
transform.localRotation = Quaternion.Euler (currentRotation);
i'm newbie. thank you.
Just like this, using the x axis if you only want to limit looking up and down.
public float turnSpeed;
private Vector2 startPos;
void On$$anonymous$$ouseDrag(){
float rotationX = Input.GetAxis ("$$anonymous$$ouse X");
float rotationY = Input.GetAxis ("$$anonymous$$ouse Y");
//left and right
if ($$anonymous$$athf.Abs (rotationX) > $$anonymous$$athf.Abs (rotationY)) {
if (rotationX > 0)
transform.Rotate (Vector3.up, -turnSpeed * Time.deltaTime);
else
transform.Rotate (Vector3.up, turnSpeed * Time.deltaTime);
}
//up and down
if ($$anonymous$$athf.Abs (rotationX) < $$anonymous$$athf.Abs (rotationY)){
if(rotationY < 0){
transform.Rotate(Vector3.right, -turnSpeed * Time.deltaTime);
}
else {
transform.Rotate(Vector3.right, turnSpeed * Time.deltaTime);
}
}
float $$anonymous$$Rotation = -45;
float maxRotation = 45;
Vector3 currentRotation = transform.localRotation.eulerAngles;
currentRotation.x = $$anonymous$$athf.Clamp(currentRotation.x, $$anonymous$$Rotation, maxRotation);
transform.localRotation = Quaternion.Euler (currentRotation);
}
thank you so much. it work but i need do some adjustment on it. thank you
i'm sorry to necro up this thread, but i used your solution, except i use arrow keys in place of mouse and i have a weird issue - whenever my x coordinate goes to 0 it bounces to the max angle permitted, which is really inconvenient since i want to have an angle range of -15,15, and i have no clue how your code can do such a thing...
I have the same issue, did you find any solution?
I've run into a similar problem others have had. I'm using the mouse buttons to rotate the object left and right, and when it goes below 0, the value goes up to over 300 and the clamp brings it down to 30, so I can't rotate right.
Any tips?
This issue comes into play with the Quaternions only being able to use data between 0 and 360 degrees. Currently working on a solution
Answer by OmarMTG · Nov 03, 2020 at 01:32 PM
public static float ConvertToAngle180(float input)
{
while (input > 360)
{
input = input - 360;
}
while (input < -360)
{
input = input + 360;
}
if (input > 180)
{
input = input - 360;
}
if (input < -180)
input = 360+ input;
return input;
}
///////////
float minRotation = -45;
float maxRotation = 45;
Vector3 currentRotation = transform.localRotation.eulerAngles;
currentRotation.y = ConvertToAngle180(currentRotation.y);
currentRotation.y = Mathf.Clamp(currentRotation.y, minRotation, maxRotation);
transform.localRotation = Quaternion.Euler(currentRotation);
///////////////////
Answer by rad1c · Jun 07, 2017 at 01:37 PM
Bumped into the same issue, was a little painful and the solution feels "hacky", but here it is. Did not generalize it, so what the code does is: allow the player to move in any direction and free look with the mouse, BUT limited to look up to "up" and "down", in other words, can't rotate and look "behind his back". Here it is, hope this helps:
//TODO add references to the player FPS camera, as well as to the Rigidbody you'll move
private float myMoveSpeed = 3.5f;
private float myYawSpeed = 500f; //could also named these variables mouse sensitivity
private float myPitchSpeed = 500f; //"x" and "y", but I find this more accurate
private void Update () {
DoMovements();
}
private void DoMovements() {
float yaw = Input.GetAxis("Mouse X") * myYawSpeed * Time.deltaTime;
float pitch = Input.GetAxis("Mouse Y") * myPitchSpeed * Time.deltaTime;
if ((yaw != 0.0f) || (pitch != 0.0f)) { //i.e. the player actually moved the mouse
transform.Rotate(0.0f, yaw, 0.0f); //horizontally: free look
//here comes the vertical:
Vector3 rot = Vector3.right * pitch * -1.0f; //*-1.0f == invert mouse movement
playerFPSCam.transform.Rotate(rot);
//here comes the 'pitch' limitation. moving up-down is 'x' coordinate, however, when
//"flipped over vertically" the 'y' and the 'z' coordinates turn into 180 (from 0),
//indicating the player is looking behind his back what I did here, and this is the
//"hacky" part, I force the cam back to either looking straight up, or straight down,
//depending on where it was flipped over; why I think it's "hacky"? Because I don't
//"test, then apply or ignore the input", but I "apply it, check if still OK,
//and if not, revert". Ugly, but couldn't find anything better as of now,
//simply because eulerAngles are 'weird': looking forward is 0 degrees,
// start turning upwards: goes down to 270, then when flips over,
//'y' and 'z' change to 180, but 'x' starts growing from 270 again. i.e. I can't test
//"if (x < 270.0f)" as it never happens... Same applies to 0-90 degrees... So...
//Test 'y' (or 'z' if you want) coord and if flipped over, force
//the cam rotation back:
if (playerFPSCam.transform.localRotation.eulerAngles.y != 0.0f) {
if (playerFPSCam.transform.localRotation.eulerAngles.x > 180.0f) {
rot.Set(playerFPSCam.transform.localRotation.eulerAngles.x - 270.0f, 0.0f, 0.0f);
} else {
rot.Set(playerFPSCam.transform.localRotation.eulerAngles.x - 90.0f, 0.0f, 0.0f);
}
playerFPSCam.transform.Rotate(rot);
}
}
}
private void FixedUpdate() {
Vector3 myMovement = new Vector3 (Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
if (myMovement != Vector3.zero) {
playerRB.MovePosition(playerRB.position + transform.rotation * myMovement * myMoveSpeed * Time.fixedDeltaTime);
myMovement = Vector3.zero;
}
}
I found Unity's solution as well. It's in Standard Assets (you can download it from the Asset Store for free). Look for Standard Assets\Characters\FirstPersonCharacter\Scripts\$$anonymous$$ouseLook.cs and ClampRotationAroundXAxis() method (LookRotation() calls it). It's a somewhat nicer solution (as of coding) yet calculation wise I'm unsure it's better.
Answer by Lairex59 · May 02, 2020 at 12:38 PM
I think this is what could help you: https://www.youtube.com/watch?v=JeF0hoJWLz4
Answer by spiritworld · Feb 06, 2021 at 12:13 PM
I use lerp, so here range is [0 - maxAngle] and it depends on input value [0, 1.0], except here angle returns to 0 after you release input but this is fine for aircraft roll if you dont want to roll over and keep the plane stable:
currentAngle = Mathf.Lerp(currentAngle, input * maxAngle, acceleration * t);
Vector3 rot = transform.rotation.eulerAngles;
rot.z = currentAngle;
transform.rotation = Quaternion.Euler(rot);