Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
3
Question by bariscigal · Nov 15, 2013 at 03:33 PM · rotationanglesdegrees

How to check object "rotated" X degrees

Hello all,

What i want to learn is not "to rotate" but "to check" a local axis rotated degrees.

To clear the question a bit: I have a steering code based on rigidbody. When I start rotating the object ,i want it to stop, when the X (or -X) degrees have been achieved in one axis.

As i see euler angles are somewhat write only angles, and quaternion angles are a bit complicated for me to grasp.

Also angles are going from 0 to 180 but i want X to be infinite. Like i want to enter 780 and want to check if it completed the 780 degrees of rotation in one axis.

This is something i have been reading for some time but couldn't find a good way for this. If there is any link regarding this issue that would be great also.

Comment
Add comment · Show 6
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 robertbu · Nov 15, 2013 at 05:06 PM 0
Share

Is the object being rotated by using torque, or are you manipulating the transform?

avatar image bariscigal · Nov 15, 2013 at 06:51 PM 0
Share

Using torque. the movement is based on physics and the input is controlled in another script by ai using 1 -1 simple inputs.

avatar image Starwalker · Nov 15, 2013 at 07:53 PM 0
Share

780 / 360 = 2.1, meaning if the user has turned the steering more than 2 times, the steering is probably broken. :P

But in general, if you want to monitor the rotation times, you can do it by euler angles itself,

 angleChecker += transform.eulerAngles.y
 
 if(angleChecker > 360 * i)
 i++;

This is not going to accurately work, but the idea is every angle is a product of eulerAngles repeating them selves, so what you need to see is how many times has the user gone above 360 degrees, that is the "i" in the above code, useing the example you gave, when (angleChecker > 360 2), he is beyond 720 degrees, 360 2 is 720. and i is 2, meaning he has rotated the steering twice

Hence, i will get you the total rotations. euler's will reset (wrap) themselves when above 360, so you can monitor either 360's or 2 * 180 turns.

avatar image bariscigal · Nov 15, 2013 at 08:39 PM 0
Share

Sorry i am sure it is something i miss about how the euler angles are working.

The thing is the angle readings i get is pretty frantic. They never go from 0 to 360 (heck not even 0 to 180) The x is going from 359 to 270 than back to 359 And the other half is from 0 to 90.

Thank you very much for the help. This is the way to follow the rotation but maybe i should look the code a bit deeper to see what is causing this.

avatar image Starwalker · Nov 15, 2013 at 10:48 PM 0
Share

Is the behavior occurring based on the input? Or something you tried from above?

Show more comments

1 Reply

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

Answer by aldonaletto · Nov 16, 2013 at 05:32 AM

You should keep an auxiliary angle measurement, since reading Euler angles isn't reliable (as you already noticed). If you rotate only about X, things are easier: measure the angle between the current forward direction and the previous one, and accumulate it in the auxiliary angle variable. The angle can be measured with Vector3.Angle, but unfortunately this function always return a positive value - you must find its polarity with Vector3.Cross, like below:

 private var lastFwd: Vector3;
 private var curAngleX: float = 0;
 
 function Start(){
   lastFwd = transform.forward;
 }
 
 function Update(){
   var curFwd = transform.forward;
   // measure the angle rotated since last frame:
   var ang = Vector3.Angle(curFwd, lastFwd);
   if (ang > 0.01){ // if rotated a significant angle...
     // fix angle sign...
     if (Vector3.Cross(curFwd, lastFwd).x < 0) ang = -ang;
     curAngleX += ang; // accumulate in curAngleX...
     lastFwd = curFwd; // and update lastFwd
   }
 }

NOTE: Accumulating the angle over time may also accumulate small errors that eventually will become noticeable.

Comment
Add comment · Show 3 · 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 robertbu · Nov 16, 2013 at 06:11 AM 1
Share

@aldonaletto - something similar was my first thought, but I assumed given the Rigidbody that he would have rotation on the 'y' and 'z' as well. If not, you code will work. But if he has arbitrary rotation, then it will fail. $$anonymous$$y fix for the problem was to move the vector into local space and then bring it onto the plane with the reference vector, but it did not work. I'm using transform.up as my reference vector. Thoughts?

 private var prevUp : Vector3;
 private var delta : float = 0.0;
 
 function Start() {
     prevUp  = transform.up;
 }
 
 function Update () {
     var v3 = transform.InverseTransformDirection(prevUp);
     v3.x = 0;
     var angle = Vector3.Angle(Vector3.up, v3);
     var sign = (Vector3.Dot(v3, Vector3.forward) > 0.0f) ? -1.0f: 1.0f;    
     delta += sign*angle;
     prevUp = transform.up;
     
     
     transform.Rotate(Input.GetAxis("Vertical"), Input.GetAxis("Horizontal"), 0.0);
 }
 
 function OnGUI() {
     GUI.Label(Rect(0,0,100,50), delta.ToString());
 
 }

  
avatar image bariscigal · Nov 16, 2013 at 09:47 AM 0
Share

Thank you very much it works fantastically. @robertbu i haven't tested your solution yet but i will after i grasp the concept soon. thank you all for the answers.

Here i have converted aldonaletto's code to c# in case anyone need it.

 using UnityEngine;
 using System.Collections;
 
 public class angleCalculator : $$anonymous$$onoBehaviour {
     
     private Vector3 lastFwd;
     private float curAngleX = 0;
 
     
     void Start () {
     lastFwd = transform.forward;
     }
     
     void Update () {
         
         Vector3 curFwd = transform.forward;
         // measure the angle rotated since last frame:
         float ang = Vector3.Angle(curFwd, lastFwd);
         if (ang > 0.01){ // if rotated a significant angle...
         // fix angle sign...
         if (Vector3.Cross(curFwd, lastFwd).x < 0) ang = -ang;
         curAngleX += ang; // accumulate in curAngleX...
         lastFwd = curFwd; // and update lastFwd
         }
         
         print (curAngleX);
     }
 }
avatar image aldonaletto · Nov 16, 2013 at 09:29 PM 0
Share

@robertbu, that's a good and very elegant idea. I tested it, and at first everything worked fine - at least when rotating one axis at a time. When rotating both axes at the same time, however, the angle informed became a lot below the expected value. I suppose that this happens because when you rotate about X and Y in the same Rotate, the object first rotates about X, then about its new local Y; when the previous up vector is flattened onto the new X plane, the angle measured is lower than what it actually rotated. A possible solution would be to convert the new up to the previous local space, what seems a lot more complicated (the previous worldToLocal matrix or rotation should be saved ins$$anonymous$$d of the up direction). Anyway, when rotating about multiple axes it's hard to define how the local angle rotation must be measured. I think that your way is perfectly good for most cases, since it doesn't depend on the world axes like $$anonymous$$e.

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

18 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 avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Trying to get the angle of a camera object based on players forward, is not distance independent 0 Answers

Quick Angles Question 2 Answers

Getting cosinus of an angle in degrees 3 Answers

Clamp rotation of sprite? 0 Answers

Euler to Quaternion conversion returns unexpected result at exactly 180 degree rotation on Y axis 0 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