• 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
Question by WillNode · Mar 03, 2015 at 12:33 PM · rotationtransformbugquaternionlerp

Unity Quaternion Problem (Should be A Bug?)

Hi, i recently has a big problem. i searc$$anonymous$$ng from any forums and QA but didn't find any luck.

so my problem is i want to move (and rotate) object by adding value on every Update() call, t$$anonymous$$s is similar like to call Vector3.Lerp() and Quaternion.Lerp(). And t$$anonymous$$s is my code :

 void Update(){
 if (doTim > 0 && Time.deltaTime > 0) {
     doTim -= Time.deltaTime;
     if (doTim != 0) {
     if (doPos)
         Behaviors [behaviorCycle].objTarget.localPosition += doPosTo / (doTimTotal / Time.deltaTime);
     if (doRot)
         Behaviors [behaviorCycle].objTarget.localRotation *= Quaternion.Euler (doRotTo / (doTimTotal / Time.deltaTime));
     if (doTim < 0) {
         if (doPos)
             Behaviors [behaviorCycle].objTarget.localPosition += doTim * (doPosTo / doTimTotal);
         if (doRot)
             Behaviors [behaviorCycle].objTarget.localRotation *= Quaternion.Euler (doTim * doRotTo / doTimTotal);
                 }
             }
         }
 }

the localPosition changes on t$$anonymous$$s Update call are WORKED correctly, but for the localRotation, it rotation will ended with very strange value.

if I rotate it by only one Axis (say, from (0,0,0) to (0,90,0)) it will rotating correctly, but if I rotate it using two or more Axis (say, from (0,0,0) to (90,90,0)) it will returning very strange value.

so, What should I do? is there somet$$anonymous$$ng I missed? I have trying to using Transform.Rotate() but it did the same t$$anonymous$$ngs.

PS : I won't use Lerp() function because the object are controlled by more than one script in my game.

Comment

People who like this

0 Show 0
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
Best Answer

Answer by Pangamini · Mar 03, 2015 at 01:30 PM

The problem is that you are doing interpolation with quaternions, but calculate the delta for your rotation from euler angles. If you were interpolating over euler angles (as a vector), the result would be different than quaternion slerp.

If you want to inrerpolate rotation smoothly towards some target, i suggest you:

  • Calculate angle between current and destination target rotation, i t$$anonymous$$nk it's angDist = Quaternion.Angle or somet$$anonymous$$ng like that. The result is float

  • Calculate how much you want to rotate in t$$anonymous$$s frame: angDiff = rotSpeed * deltaTime

  • Calculate the ratio of the total angle vs what you want to move, and feed that to slerp (not lerp, never lerp for quaternions that represent rotations). That would be: ratio = angDiff / angDist

  • Last, you can do the Slerp correctly (as it's meant to be, i never understand people who use deltaTime as lerp/slerp factor!!): newRotation = Quaternion.Slerp(oldRotation, targetRotation, ratio )

Comment

People who like this

0 Show 2 · 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 WillNode · Mar 04, 2015 at 09:02 AM 0
Share

ok, i will make the code and test it now.

avatar image WillNode · Mar 04, 2015 at 11:02 AM 0
Share

indeed! even i didn't use all of your solution, but using Slerp() function is a great idea. my final code :

 void Update ()
     {
     if (doTim > 0 && Time.deltaTime > 0) {
         doTim -= Time.deltaTime;
         if (doTim != 0) {
             if (doPos)
                 Behaviors [behaviorCycle].objTarget.localPosition += doPosTo / (doTimTotal / Time.deltaTime);
             if (doRot)
                 Behaviors [behaviorCycle].objTarget.localRotation *= Quaternion.Slerp (Quaternion.identity, doRotTo, Time.deltaTime / doTimTotal);
             if (doTim < 0) {
                 if (doPos)
                     Behaviors [behaviorCycle].objTarget.localPosition += doTim * (doPosTo / doTimTotal);
                 if (doRot)
                     Behaviors [behaviorCycle].objTarget.localRotation *= Quaternion.Inverse( Quaternion.Slerp (Quaternion.identity, doRotTo, -doTim / doTimTotal));
             }
         }
     }
 }

thanks for the great answer!

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

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

Related Questions

How to smoothly rotate to certain directions using input axis 1 Answer

Need to check transform.rotation 1 Answer

How do you smoothly transition/Lerp into a new rotation? 3 Answers

How to ROTATE an object without slowing the ends (lerp) 3 Answers

Get slerp to work just as LookAt(,Vector3.right) does 1 Answer


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