- Home /
Limiting rotation of object in script
Hi
The solution to this problem is probably quite simple but it is really troubling me.
I'm trying to make my first small project in unity. It is one of those tilting labyrinth games where you try to lead a marble around a maze without it falling into a hole. I have the game board rotating but want the degree to which it can rotate to be limited so it cant flip upside down and such. I used this script which I attached to the maze playing board object.
// The maximum angle the board can tilt public float MaxTiltAngle; Vector3 initialRotation; // Use this for initialization void Start () { // Get initial rotation initialRotation = this.transform.rotation.eulerAngles; } // Update is called once per frame void Update () {
// Add torque to the gameboard based on input if(Input.GetKey(KeyCode.LeftArrow)) this.rigidbody.AddTorque(0,0,1); if(Input.GetKey(KeyCode.RightArrow)) this.rigidbody.AddTorque(0,0,-1); if(Input.GetKey(KeyCode.UpArrow)) this.rigidbody.AddTorque(1,0,0); if(Input.GetKey(KeyCode.DownArrow)) this.rigidbody.AddTorque(-1,0,0); // Get the current rotation Vector3 tempRotation = this.transform.rotation.eulerAngles; // Restrict rotation along x and z axes to the maximum tilt angle tempRotation.x = Mathf.Clamp(tempRotation.x, initialRotation.x - MaxTiltAngle, initialRotation.x + MaxTiltAngle); tempRotation.z = Mathf.Clamp(tempRotation.z, initialRotation.z - MaxTiltAngle, initialRotation.z + MaxTiltAngle); // Set the objects rotation this.transform.rotation = Quaternion.Euler(tempRotation); }
When the game plays without the tilting being restricted it works fine but when I try and clamp the angle to 20 degrees or so the game board will no longer rotate. Instead it very slowly moves around the game scene even though I fully constrained the position along all axes in the inspector.
Answer by aldonaletto · Oct 12, 2012 at 07:36 PM
This definitely isn't the best way to do what you want: rigidbodies are wild and hard to control, even more when you want to restrict rotation to certain angle.
A better way would be to get the initial eulerAngles (as you're currently doing) and control them mathematically, assigning the result to transform.eulerAngles:
// The maximum angle the board can tilt
public float MaxTiltAngle = 20.0f;
public float tiltSpeed = 30.0f; // tilting speed in degrees/second
Vector3 curRot;
float maxX;
float maxZ;
float minX;
float minZ;
void Start () {
// Get initial rotation
curRot = this.transform.eulerAngles;
// calculate limit angles:
maxX = curRot.x + MaxTiltAngle;
maxZ = curRot.z + MaxTiltAngle;
minX = curRot.x - MaxTiltAngle;
minZ = curRot.z - MaxTiltAngle;
}
void Update () {
// "rotate" the angles mathematically:
curRot.x += Input.GetAxis("Vertical") * Time.deltaTime * tiltSpeed;
curRot.z += Input.GetAxis("Horizontal") * Time.deltaTime * tiltSpeed;
// Restrict rotation along x and z axes to the limit angles:
curRot.x = Mathf.Clamp(curRot.x, minX, maxX);
curRot.z = Mathf.Clamp(curRot.z, minZ, maxZ);
// Set the object rotation
this.transform.eulerAngles = curRot;
}
Hi Aldo Naletto Thanks. Your answer is greatly appreciated.
I have a similar problem. This solution may work for "slow" rotations but it will fail with fast rotations because you will get ball rigidbody "inside" board rigidbody and it will produce unnatural behaviours. And that will happen because the transform.eulerangles doesn´t care about collisions, it will move the board to the next position no matter what. If the position changes too fast, it will go through the ball.
You're correct... were you able to fix it for fast rotations?
You're right: the ball may pass through the board if the board moves too fast. This issue can be avoided by limiting the speed.
The hacky way we solved for faster rotations was to cover our object (mesh) with many box colliders. This way the box colliders will make sure the object does not go through. You just need to place as much as small box colliders to match/cover your mesh collider. Again not a great solution but works well for us. Also make sure the colliding object also has a collider (i.e. Box or Sphere collider).
Your answer
Follow this Question
Related Questions
Rotate floor plane in-game via C# script 1 Answer
Rotation according to gravity 1 Answer
Set the rotation reference to an direction 0 Answers