- Home /
Limiting rotation of an object
Hi there, i'm doing a "platform/balance/roll-a-ball" game, in wich the ground will be platforms that are tilted via the players input, and the ball moves around based on gravity.
The idea is to rotate the platforms (a Cube or Plane) in the x and z axises, so it should always be looking in the same direction.
My issues are as follow:
As i rotate the platform, on the x and z axis, it starts to slightly rotate on the y axis as well, so the control starts to get more and more complicated.
The platform rotation is limited to +-45° on each axis, and that works fine when i tilt in only 1 axis, when i start doing both, it goes beyond 45° and i get something like 80°.
I created variables to store the rotation created by the script, but when that anomalous rotation happens, the actual X or Z rotation is beyond what the control variable has stored.
public float turnSpeed = 1.5f; // speed the platform tilts private float maxtiltAngle = 45.0f; // max incline angle public float vrotationTotal = 0.0f; // total rotation on the X axis public float hrotationTotal = 0.0f; // total rotation on the Z axis
void FixedUpdate () { float vrotation = turnSpeed*Input.GetAxis("Vertical"); // input vertical, rotates X axis float hrotation = turnSpeed*Input.GetAxis("Horizontal"); // input horizontal, rotates Z axis if (Input.GetAxis ("Horizontal") > 0.01f) // if input direction is positive { if (hrotationTotal <= maxtiltAngle) // and the current rotation is less than the max, it will apply rotation { transform.Rotate (0, 0, -hrotation); //hrotation is negative to make it go in the same direction as the arrow keys hrotationTotal += turnSpeed*Input.GetAxis("Horizontal"); // modify the rotationTotal variable to keep updated } } if (Input.GetAxis ("Horizontal") < 0.01f) // if input negative { if ( hrotationTotal >= -maxtiltAngle) // and the current rotation is less than the max (on the other direction), it will apply rotation { transform.Rotate (0, 0, -hrotation); hrotationTotal += turnSpeed*Input.GetAxis("Horizontal"); } } if (Input.GetAxis ("Vertical") > 0.01f) // if input direction is positive { if (vrotationTotal <= maxtiltAngle) // and the current rotation is less than the max, it will apply rotation { transform.Rotate (vrotation, 0, 0); vrotationTotal += turnSpeed*Input.GetAxis("Vertical"); } } if (Input.GetAxis ("Vertical") < 0.01f) // if input negative { if ( vrotationTotal >= -maxtiltAngle) // and the current rotation is less than the max (on the other direction), it will apply rotation { transform.Rotate (vrotation, 0, 0); vrotationTotal += turnSpeed*Input.GetAxis("Vertical"); } }
So basically, what i need is:
a) Is there a way to limit rotation on a specific axis so it does not happen? tried applying a rigidbody with constraints but didn't work. b) what would be a better way to limit the rotation angle? how can i get the actual rotation from the object so it does not exceed the limit i want to place?
Thanks in advance!!
PS: yeah, i'm reaaaally a coding noob, sorry if this is a silly question...
Answer by Anxo · Oct 24, 2014 at 05:15 PM
Well Instead of using Rotate I might manipulate the transform.euler as it would be more direct but that is just preference.
The reason you are going past your rotation limit is b/c your vrotation total is by the input axis at every frame. So you are telling it every frame, rotate this object on x asis by one more than it currently is.
You are not limiting the rotation itself you are just limiting how much can be added to the rotation before the variable changes.
You want something like
void FixedUpdate(){
// all your code is here
float currentX = platform.transform.euler.x;
if(currentX > 100 )
currentX = 100;
// repeate for y and z and negative numbers
// or you could also just use MathF.Clap
// then apply the limitation
Vector3 newEuler = new Vector3 (currentX,currentY,currentZ);
platform.transform.euler = newEuler;
}
WUCC check for errors
Hi, thanks for the help!
I tried your code, but i'm having trouble now, because it makes the plane snap to 45, either in x or z... on the plus side, it doesn't rotate on Y anymore, and doesn't go past 45 on X or Z...
The other thing i noticed, is that if I apply the rotation through transform.eulerAngles, ins$$anonymous$$d of Transform.Rotate, the rotation stays as long as i mantain the key pressed, if i release it, the rotation goes back to 0.
for the snapping just lower the turnspeed dramatically.
The reason why it resets is simply because you are setting the value to 0 at the start of every frame when you are not pressing the button, because you are still applying "horizontal" rather or not the input gets a value greater than 0.
float hrotation = turnSpeed*Input.GetAxis("Horizontal"); // input horizontal, rotates Z axis
just rethink the logic a little and you will get it. you can move the hrotation outside of the function or you can just apply the stuff in a much more direct fashion.
void FixedUpdate(){
Vector3 currentEuler = platoform.transform.euler;
Vector3 wantedEuler = new Vector3 (currentEuler.x += (turnspeed*Input.GetAxis("Horizontal")),0, same as x for z);
Vector3 adjustedEuler = new Vector3($$anonymous$$athf.Clap(wantedEuler.x,-45,45),0, same for Z as for X);
platform.transform.euler = adjustedEuler;
}
Out of habit, I would keep the none physics commands out of FixedUpdate and move them to Update, the speed is still constant when you add a *Time.deltaTime to your speeds. But this way if you have physics, they can run own a different thread than the none physics and wont hold up your other calculations. <--- I am not sure this is true but I always assumed for this to be the case.
WUCC check for errors.
Thanks for the answer!!!
I tried that code, and it simplyfied a lot... but there's one little snag...
Since Euler Angles go from 0 to 360°, there's no -45, so i can't clamp that way, when the movement goes the other direction (right to 359.9 or less) it clamps right back to 45°... Any Idea on how to fix that? maybe 2 clamps or maybe clamping outside before creating the adjusted vector...
On the Update thing, yeah, i know... thanks for re$$anonymous$$ding me, I started the project using forces to rotate the plane but it was maddening, so i went back to just rotating the plane, and forgot to change it back...
PS: Thanks for your help!! it's been an enriching experience!
Finally Fixed it! using a mix of your las answer and creating a function to make custom Clamping i was able to make it behave as i wanted.
Thanks a lot for the help and hints... Now, onto making the camera work properly, and finding a good angle for the game... :P
Your answer
Follow this Question
Related Questions
how to limit rotation 2 Answers
I want to restrict the rotation with the following Script,I want to restrict tranform.Rotation 0 Answers
Limiting rotation of object, specifically using scroll wheel 2 Answers
Rotating hinge joint over 180° with angular limit 1 Answer
How to limit the rotation of an object 2 Answers