- Home /
limit rotation using math.clamp
hey everyone i m in a project where i have to limit rotation of my ,targetItem( a gameobject) to some digress say 180 to 350 degree.i am able to do some portion of it using math.clamp when i go towards 180 everything works fine but when i go beyond 350 degree it sets value of my targetItem to 180. how can i fix this problem so that ,when i try to go beyond 350 it shuld not reset my value to 180 and stay at 350 degree
here is my code
if(hit.transform.name=="stear" )
{
var MinClamp = 180;
var MaxClamp = 350;
if(Input.GetTouch(i).phase == TouchPhase.Moved)
{
targetItem.transform.Rotate(0, theTouch.deltaPosition.x * rotationRate,0,Space.World);
targetItem.transform.rotation.eulerAngles = new Vector3( 0, Mathf.Clamp(targetItem.transform.rotation.eulerAngles.y,MinClamp,MaxClamp),0);
print(targetItem.transform.rotation.eulerAngles.y);
}
}
for more detail u can see the log and projet in youtube link given project live in action in youtube
Answer by whydoidoit · Nov 13, 2013 at 12:49 PM
public static float ClampAngle(float angle, float min, float max)
{
angle = Mathf.Repeat(angle, 360);
min = Mathf.Repeat(min, 360);
max = Mathf.Repeat(max, 360);
bool inverse = false;
var tmin = min;
var tangle = angle;
if(min > 180)
{
inverse = !inverse;
tmin -= 180;
}
if(angle > 180)
{
inverse = !inverse;
tangle -= 180;
}
var result = !inverse ? tangle > tmin : tangle < tmin;
if(!result)
angle = min;
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;
}
hey whydoidoit (sorry i dont know ur name ) i m new to unity so i dont understand how and where to use ur code will u plz more polite to tell me how use ur code
Use it ins$$anonymous$$d of $$anonymous$$athf.Clamp
if(hit.transform.name=="s$$anonymous$$r" )
{
var $$anonymous$$inClamp = 180;
var $$anonymous$$axClamp = 350;
if(Input.GetTouch(i).phase == TouchPhase.$$anonymous$$oved)
{
targetItem.transform.Rotate(0, theTouch.deltaPosition.x * rotationRate,0,Space.World);
targetItem.transform.rotation.eulerAngles = new Vector3( 0, ClampAngle(targetItem.transform.rotation.eulerAngles.y,$$anonymous$$inClamp,$$anonymous$$axClamp),0);
print(targetItem.transform.rotation.eulerAngles.y);
}
}
Answer by aldonaletto · Nov 13, 2013 at 01:32 PM
Reading transform.eulerAngles is always a bad idea: it's actually transform.rotation converted to a 3-axes (Euler) representation; since there are several XYZ combinations that correspond to a single rotation, Unity may (and often will) return the "wrong" one (a valid XYZ combination, but not the one you expect).
When you must rotate something to precise angles or inside precise limits, the best alternative is to save the angle in a member variable (declared outside any function) and "rotate" it mathematically, then assign the angle to transform.eulerAngles (writing to eulerAngles works fine). Your code could become something like this:
// declare this variable outside any function:
private var angle: Vector3 = Vector3.zero;
...
if (hit.transform.name=="stear" )
{
if(Input.GetTouch(i).phase == TouchPhase.Moved)
{
// "rotate" angle.y mathematically:
angle.y += theTouch.deltaPosition.x * rotationRate;
// clamp it to the desired limits:
angle.y = Mathf.Clamp(angle.y, 180, 350);
// update target actual rotation:
targetItem.transform.eulerAngles = angle;
}
}
Off topic: @aldonaletto can you suspend users? There's a spam bot thing in the moderation reject queue.
I've just suspended that damned arab spammer a couple of $$anonymous$$utes ago. The system accepted the action, but don't know if it's really doing anything - at least there's no more spam right now.
aldonaletto same problem occured, when i rotate towards 350 degree the values goes to 180,like the previous one u can see the video of what is happening even when i make changes in my project (click on it)
Ok, the problem is the %360: if for instance you move from 320 to 372 in a single frame, the modulo 360 operator converts the result to 12 (372 $$anonymous$$us 360), which's clamped to 180. Just remove that unhappy %360:
// "rotate" angle.y mathematically:
angle.y += theTouch.deltaPosition.x * rotationRate;
...
This modulo operator is unnecessary (and undesired), since the angle is limited by $$anonymous$$athf.Clamp. The answer is fixed now.
first off all thanks for your support it really did solve my problem :) ,
my default location is 270 when i try to move,ins$$anonymous$$d of moving from 270 it first go to 180 and then start to rotate,no mater which direction i want it to move (either on 270+ or 270-).
Your answer
Follow this Question
Related Questions
Limit Rotations with Min and Max on Mobile 1 Answer
Clamping RotateAround 1 Answer
Turrets acting oddly when clamped 1 Answer
Clamp rotation using Quaternion.Euler does not work 2 Answers
Rotate Camera around object with touch 0 Answers