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
1
Question by Scenia · Jun 16, 2013 at 11:18 PM · rotationquaterniondirectionslerp

Rotation direction in coroutine

I have a weird problem concerning rotating objects. The object in question is shaped like a plate and positioned horizontally. Now I want to flip it over and turn it into vertical position at the same time. Basically, I want its rotation to go from Euler(90,0,0) to Euler(270,90,0). My problem is, I want it to go there in the obvious direction, increasing both angles, but it rotates the other way. I don't want to use animations, this is not the only rotation I'll have long term and a coroutine just seems better suited.

I've tried quaternion.slerp, quaternion.lerp, vector3.lerp in combination with Euler and eulerAngles as well as splitting the rotation into two parts from start to the midway rotation and from there to the target. It keeps rotating in the wrong direction. I've also tried using (-90,90,0) as the target, also when I try to change the angles at runtime in the inspector, it keeps converting them to something strange... Debug.log tells me the Euler angles are right, but it either converts them wrong when going to a quaternion or does something I have no idea of. I'm really clueless, what am I doing wrong?

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

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by robertbu · Jun 16, 2013 at 11:33 PM

There are two issues here. The first is that Quaternion.Slerp() takes the shortest distance between the two rotation, so it will not go around the long way. The second issue is there are multiple euler angle representations for any "physical" rotation, so you cannot depend on Unity using any specific one. As you found out, you can set an angle to something like (180,0,0), and immediate read it back and get (0,180,180) (which is the same physical rotation).

One solutions is to manage the angle yourself. That is to create and use your own Vector3 and treat Transform.eulerAngles as "write-only." Never read eulerAngles and expect any particular representation. Since you never cross the 0/360 boundary for your target angles above, you can do something like:

 var v3Rot = Vector3(90,0,0);
 var v3Dest = Vector3(270,90,0);
 
 var speed = 4.0;
  
 function Start () {
     transform.eulerAngles = v3Rot;
 }
 
 function Update() {
 
     v3Rot = Vector3.MoveTowards(v3Rot, v3Dest, speed * Time.deltaTime);
     Debug.Log(v3Rot);
     transform.eulerAngles = v3Rot;
 }
Comment
Add comment · Show 8 · 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 Scenia · Jun 17, 2013 at 12:25 PM 0
Share

I've tried something similar, only using eulerAngles to get my initial Vector3s, it didn't work and still turned the wrong way. Here's what I did:

 transform.rotation = Quaternion.Euler(90,0,0);
 StartCoroutine("RotateTo", Quaternion.Euler(270,90,0));
 
 function RotateTo (target : Quaternion) {
     var start : Vector3 = transform.rotation.eulerAngles;
     Debug.Log(start); // This correctly showed (90,0,0)
     var vtarget : Vector3 = target.eulerAngles;
     Debug.Log(vtarget); // This also showed (270,90,0) as intended
     var i : float = 0.0;
     var eulerlerp : Vector3;
     while (i<1.0) {
         i += Time.deltaTime;
         eulerlerp = Vector3.Lerp(start, vtarget, i);
         Debug.Log(eulerlerp); // This showed the correct angle as well
         transform.rotation = Quaternion.Euler(eulerlerp);
         yield;
     }
     transform.rotation = target;
 }

Is the problem my use of Quaternion.Euler? All Debug.Logs showed the intended angle, but the angles shown in the Inspector don't match and the actual rotation of the object is also wrong, it still rotates to (0,45,0), then to (-90,90,0) which is the same correct target rotation, but the wrong way to get there.

avatar image aldonaletto · Jun 17, 2013 at 01:15 PM 0
Share

This code should work - unless you want to go in the direction (90,0,0) to (-90,90,0). Are you sure that RotateTo is called only once? If called multiple times, the resulting behaviour will be very weird - each time you call RotateTo, a new coroutine instance starts to run, and all of them will fight for the control of the object. Sometimes is better to make sure of this with a boolean variable:

 var rotating = false;

 function RotateTo(...){
   if (rotating) return; // abort other calls while rotating
   rotating = true; // I'm start rotating now
   ... // your code
   rotating = false; // rotation finished
 }
avatar image robertbu · Jun 17, 2013 at 02:33 PM 0
Share

@Scenia - You cannot use a Quaternion to pass the eulerAngles! That was one of the main point of my original post. You cannot read back eulerAngles and expect any specific value. For this to work, you have to manage the angles in your own Vector3, and never read back eulerAngles form a Quaternion.

avatar image Scenia · Jun 17, 2013 at 07:09 PM 0
Share

Ah, I see. Do I have to do that consistently in the entire project? So I basically don't use transform.rotation and transform.localRotation at all? Also, it should still work when I roll over 0°, shouldn't it? The only problem is when I get over 360, which never happens since I set the angles. Or does transform.eulerAngles only take positive values?

aldonaletto - Good point. In this specific case, I want new coroutines to replace old ones, so I always use StopAllCoroutines() before StartCoroutine().

avatar image robertbu · Jun 17, 2013 at 07:27 PM 0
Share

There are lots of good uses for Quaternions, but you cannot depend on the return value being any particular euler representation. So whether to use them will depend on the rotation problem you are trying to solve. In theory, you could unwind and normalize the return values to solve your problem, but it is far easier to just keep your own Vector3. As for the 0/360 boundary, Vector3.Lerp() will treat the values you enter literally. So if you want to go from 350 degrees to 20 degrees the short way, you just change the representation to go from 710 degrees to 680 degrees. Also since it treats numbers literally, you can make multiple turns...go from 0 to 1080 for three turns.

Show more comments
avatar image
0

Answer by abrown4887 · Dec 03, 2013 at 09:29 AM

I'm not sure if I'm answering your question or not but if you are having problems with the rotation taking the long way instead of the short way you might check out this question on SO about determining rotation direction

http://gamedev.stackexchange.com/questions/45412/understanding-math-used-to-determine-if-vector-is-clockwise-counterclockwise-f/45434?noredirect=1#comment75790_45434

Comment
Add comment · 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

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

17 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

Related Questions

Rotate object to target position 1 Answer

Lerp 180 degrees while holding B and lerp back 180 degrees when let go of B. 2 Answers

LookRotation Vector3 is Zero, Yet Slerp Still Rotates? 2 Answers

Quaternion based slerp to make homing projectile doesn't turn 1 Answer

Unity thinks my Quaternion is a Float 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