- Home /
How do I clamp my rotation?
The player is in first-person, as humanoid model. To other players, when they look up, their torso rotates slightly vertically. It works the same way when I look down. This can also be observed in the game "Rust", by Garry Newman. Here is my script, that is attatched to the spine.
var speed : float = 5;
var torsoRotation : float = 0;
function Update() {
torsoRotation = Input.GetAxis("Mouse Y") * speed;
Mathf.Clamp(torsoRotation, -90, 90);
transform.Rotate(0, 0, -torsoRotation, Space.Self);
}
It works, except for the clamp. I can infinitely roll my upper body. I am suspicious at the fact that in the inspector, my torsoRotation
is equal to 0. When I move the mouse up or down fairly quickly, it changes to about 0.5 or 1. When I stop using the mouse, it drifts back to 0. What is happening, and how can I fix it?
The only clamp you've implemented is each frame limit the movement between -90 and 90 degrees.
I think I see what you're saying! Do you know how I could actually limit the rotation that you see?
You would need to $$anonymous$$athf.Clamp(gameObject.eulerAngles.y, -90, 90);
Here is my new code:
var speed : float = 5; var torsoRotation : float = 0; var maximumRotation : float = 359; var $$anonymous$$imumRotation : float = 80; var torso : GameObject;
function Update() { torsoRotation = Input.GetAxis("$$anonymous$$ouse Y") * speed; $$anonymous$$athf.Clamp(torso.eulerAngles.y, maximumRotation, $$anonymous$$imumRotation); torso.transform.Rotate(0, 0, -torsoRotation, Space.Self); } It still doesn't work. I can run the game, but errors show up every time I move the mouse. :/
Answer by whydoidoit · Mar 10, 2014 at 12:44 PM
Try this:
function Update() {
torsoRotation = Input.GetAxis("Mouse Y") * speed;
transform.Rotate(0, 0, -torsoRotation, Space.Self);
transform.eulerAngles.y = Mathf.Clamp(transform.eulerAngles.y, -90, 90);
}
Clamping just returns a value that you have to set into the rotation yourself. You need this after you've applied your rotation. However, this may still cause strange flicking, if so you might need to use a cleverer clamping function that understands angles.
It worked! However, I really don't know where to start when it comes to your "cleverer clamping function" idea. Could you lead me in the right direction? Thank you so much!
Well this is my ClampAngle function:
public static float ClampAngle(float angle, float $$anonymous$$, float max)
{
angle = $$anonymous$$athf.Repeat(angle, 360);
$$anonymous$$ = $$anonymous$$athf.Repeat($$anonymous$$, 360);
max = $$anonymous$$athf.Repeat(max, 360);
bool inverse = false;
var t$$anonymous$$ = $$anonymous$$;
var tangle = angle;
if($$anonymous$$ > 180)
{
inverse = !inverse;
t$$anonymous$$ -= 180;
}
if(angle > 180)
{
inverse = !inverse;
tangle -= 180;
}
var result = !inverse ? tangle > t$$anonymous$$ : tangle < t$$anonymous$$;
if(!result)
angle = $$anonymous$$;
inverse = false;
tangle = angle;
var tmax = max;
if(angle > 180)
{
inverse = !inverse;
tangle -= 180;
}
if(max > 180)
{
inverse = !inverse;
tmax -= 180;
}
result = !inverse ? tangle < tmax : tangle > tmax;
if(!result)
angle = max;
return angle;
}
Thanks! I really don't know how to specifically implement this into my script though. I'm not quite this advanced in Unity. Do I change any variables? Do I paste it into my script? Sorry to bother!
You'd add that to a class and then just use:
var clampedAngle = TheClassYouAddedItTo.ClampAngle(someAngle, $$anonymous$$imumAngle, maximumAngle);
I made a C# class/script, and I named it clampingAngle
. It looks like this:
using UnityEngine;
using System.Collections;
public class clampingAngle : $$anonymous$$onoBehaviour {
public static float ClampAngle(float angle, float $$anonymous$$, float max)
{
angle = $$anonymous$$athf.Repeat(angle, 360);
$$anonymous$$ = $$anonymous$$athf.Repeat($$anonymous$$, 360);
max = $$anonymous$$athf.Repeat(max, 360);
bool inverse = false;
var t$$anonymous$$ = $$anonymous$$;
var tangle = angle;
if($$anonymous$$ > 180)
{
inverse = !inverse;
t$$anonymous$$ -= 180;
}
if(angle > 180)
{
inverse = !inverse;
tangle -= 180;
}
var result = !inverse ? tangle > t$$anonymous$$ : tangle < t$$anonymous$$;
if(!result)
angle = $$anonymous$$;
inverse = false;
tangle = angle;
var tmax = max;
if(angle > 180)
{
inverse = !inverse;
tangle -= 180;
}
if(max > 180)
{
inverse = !inverse;
tmax -= 180;
}
result = !inverse ? tangle < tmax : tangle > tmax;
if(!result)
angle = max;
return angle;
}
}
Is this correct? Then I added the variable into my mouseRotate script, that rotates the torso:
var speed : float = 5;
var torsoRotation : float = 0;
var maximumRotation : float = 359;
var $$anonymous$$imumRotation : float = 80;
var clampedAngle = clampingAngle.ClampAngle(someAngle, $$anonymous$$imumRotation, maximumRotation);
function Update() {
torsoRotation = Input.GetAxis("$$anonymous$$ouse Y") * speed;
transform.Rotate(0, 0, -torsoRotation, Space.Self);
transform.eulerAngles.y = $$anonymous$$athf.Clamp(transform.eulerAngles.y, -90, 90);
}
How do I use the function/variable? If I'm completely confused with what I'm supposed to be doing, let me know.
Answer by DerDicke · Jan 16, 2018 at 08:42 PM
Old thread, but problem was never solved. Best solution for me was:
float ClampAngle(float angle, float from, float to)
{
// accepts e.g. -80, 80
if (angle < 0f) angle = 360 + angle;
if (angle > 180f) return Mathf.Max(angle, 360+from);
return Mathf.Min(angle, to);
}
void RotateInFrame()
{
if (!Input.GetMouseButton(1)) return; // RMB down
float mx = Input.GetAxis("Mouse X") * Time.deltaTime * rotSpeed;
float my = Input.GetAxis("Mouse Y") * Time.deltaTime * rotSpeed;
Vector3 rot = transform.rotation.eulerAngles + new Vector3(-my, mx, 0f); //use local if your char is not always oriented Vector3.up
rot.x = ClampAngle(rot.x, -60f, 60f);
transform.eulerAngles = rot;
}
Good luck!
Your code works perfectly, thank you!!!, simple and works
There looks like there's some parts of this script missing, @DerDicke
Answer by Lairex59 · May 02, 2020 at 12:33 PM
Here it's explained well https://www.youtube.com/watch?v=JeF0hoJWLz4
Answer by Amyr · Dec 25, 2021 at 03:22 PM
This worked fine for me. But since I am moving in delta steps, I had to add this in order to clamp it right:
float deltaAngle = context.ReadValue<float>();
float clampAngle = ClampAngle(target.eulerAngles.x + deltaAngle);
deltaAngle = clampAngle - target.eulerAngles.x;
target.Rotate(target.right, deltaAngle, Space.World);
Notice I am using a new input system event call to look up and down using the mouse Y axis. Also, I made the ClampAngle function a private member of my class, and removed the min and max parameters, since those are user defined parameters, and I made them members of the same class. Then I rotate the target Transform along its right axis.
Work as a charm!
Your answer
![](https://koobas.hobune.stream/wayback/20220613135836im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Is anyone able to fix my code? 3 Answers
Mouse Look Controller that can rotate on the Z axis 1 Answer
Restricting GameObject Rotation 1 Answer
How to use mathf.clamp? 2 Answers