Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by NateK · Oct 12, 2012 at 06:36 PM · rotationquaternionangleconstraintlimitation

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.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer

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;
 }
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NateK · Oct 12, 2012 at 09:58 PM 0
Share

Hi Aldo Naletto Thanks. Your answer is greatly appreciated.

avatar image tourajv · Sep 18, 2018 at 10:02 PM 0
Share

Thanks so much! works perfectly.

avatar image Baalhug · Sep 18, 2018 at 10:36 PM 0
Share

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.

avatar image tourajv Baalhug · Sep 19, 2018 at 08:16 AM 0
Share

You're correct... were you able to fix it for fast rotations?

avatar image aldonaletto Baalhug · Sep 19, 2018 at 11:15 PM 0
Share

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.

avatar image tourajv aldonaletto · Sep 25, 2018 at 09:09 PM 0
Share

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

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

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

Make a side of an object LookAT another object 1 Answer

Rotating an object so that the direction between it's children matches the forward of rotating object 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges