• 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 FreetimeCoder · Jun 21, 2013 at 02:49 PM · quaternionpathinterpolate

Not interpolate quaternion on shortest path?

Hi,

I have been searching a long time but I did not find something that hints at a solution. Basically I want to smoothly interpolate between two Rotations. However I do not want to interpolate along the shortest path.

When I use Quaternion.Lerp, SLerp or RoateTowards it would rotate 90 degrees when interpolating between (in eulers) (0,270,0) and (0,0,0), but I want it to rotate 270 degrees.

I tried using eulerAngles on both source and target rotation, interpolating the vectors and reconverting them into quaternions with Quaternion.Euler but that gives me the same results.

Is there an inbuilt way to use this "non-optimal" interpolation?

greetings

Comment
Add comment · Show 1
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 FreetimeCoder · Jun 21, 2013 at 03:13 PM 0
Share

I was just about to write that this does not work either, since I already tried it, but it got me thinking.

$$anonymous$$y problem originated from the fact that rotation.eulerAngles is clamped between 0 and 360 and that is why I was interpreting the interpolation wrong.

I found that localEulerAngles contains the rotation displayed in the editor, so I can work with that.

Thank you for your time

Edit: how do I check a question answered? Does convert to answer do this, or does this only convert my comment?

3 Replies

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

Answer by robertbu · Jun 21, 2013 at 02:53 PM

If you do some searching around on UA, you will find a number of answers to this question. One answer is to treat eulerAngles as write-only and maintain your own Vector3. Here is one of those answers:

http://answers.unity3d.com/questions/475760/rotation-direction-in-coroutine.html

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 robertbu · Jun 21, 2013 at 03:37 PM 0
Share

@FreetimeCoder - eulerAngles has a habit of changing representation on you. You can get around the 0/360 boundary by changing the representation in the Vector3 you maintain.

avatar image FreetimeCoder · Jun 23, 2013 at 07:51 AM 0
Share

Ok, but is there a reason not to use localEulerAngles? From what I can tell it does exactly what I need.

avatar image robertbu · Jun 25, 2013 at 11:57 PM 0
Share

@FreetimeCoder - As explained in the answer at the link provided, eulerAngles can change its representation. Write a bit of code that sets the eulerAngles to (180,0,0), and then use a Debug.Log() statement to read it back. You will get (0,180,180). eulerAngles changes in a predictable pattern, so if you are careful, it may work for you. But as stated, it is safer to keep your own Vector3 and never read eulerAngles.

avatar image FreetimeCoder · Jun 26, 2013 at 01:41 PM 0
Share

I see what you mean, however I cannot use that method because the first time I get a rotation is when the level started and I read localEulerAngles from the gameobject's transformation. I never modify it afterwards only interpolate something else between different objects' transformations.

avatar image FreetimeCoder · Jun 30, 2013 at 03:00 PM 0
Share

Ok, I found that transform.localRotation is much better than localEulerAngles, because the later sometimes even changes between in-editor and in-game while the localRotation Quaternion does not.

(I must confess this again takes me back to the "shortest path" thing, but I have given up on trying to acheive a perfect solution)

I think this solves this topic.

Show more comments
avatar image
4

Answer by Maeslezo · Jan 27, 2017 at 09:14 AM

I had the same problem, so I have written the lerp and slerp myself, with a flag to indicate whether you want to force the short way or not. I am pretty sure that Unity checks that to invert the rotation. With this code, you can indicate if you want that behaviour.

I have checked myself and it seems it works ok, but check yourself just in case:

 public static class QuaternionExtension
  {
      public static Quaternion Lerp(Quaternion p, Quaternion q, float t, bool shortWay)
      {
          if (shortWay)
          {
              float dot = Quaternion.Dot(p, q);
              if (dot < 0.0f)
                  return Lerp(ScalarMultiply(p, -1.0f), q, t, true);
          }
  
          Quaternion r = Quaternion.identity;
          r.x = p.x * (1f - t) + q.x * (t);
          r.y = p.y * (1f - t) + q.y * (t);
          r.z = p.z * (1f - t) + q.z * (t);
          r.w = p.w * (1f - t) + q.w * (t);
          return r;
      }
  
      public static Quaternion Slerp(Quaternion p, Quaternion q, float t, bool shortWay)
      {
          float dot = Quaternion.Dot(p, q);
          if (shortWay)
          {
              if (dot < 0.0f)
                  return Slerp(ScalarMultiply(p, -1.0f), q, t, true);
          }
  
          float angle = Mathf.Acos(dot);
          Quaternion first = ScalarMultiply(p, Mathf.Sin((1f - t) * angle));
          Quaternion second = ScalarMultiply(q, Mathf.Sin((t) * angle));
          float division = 1f / Mathf.Sin(angle);
          return ScalarMultiply(Add(first, second), division);
      }
  
  
      public static Quaternion ScalarMultiply(Quaternion input, float scalar)
      {
          return new Quaternion(input.x * scalar, input.y * scalar, input.z * scalar, input.w * scalar);
      }
  
      public static Quaternion Add(Quaternion p, Quaternion q)
      {
          return new Quaternion(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w);
      }
  }

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 LevonVH · Jan 28, 2021 at 12:24 PM 0
Share

Great solution @$$anonymous$$aeslezo ! Thank you.

avatar image Bunny83 · Jan 28, 2021 at 01:17 PM 0
Share

An implementation that's a bit more optimised would be:

   public static Quaternion Slerp(Quaternion p, Quaternion q, float t, bool shortWay)
   {
       float dot = Quaternion.Dot(p, q);
       float sign = (shortWay && dot < 0.0f) ?-1f : 1f;
       float angle = Mathf.Acos(dot * sign);
       float division = 1f / Mathf.Sin(angle);
       float t0 = Mathf.Sin((1f - t) * angle) * division * sign;
       float t1 = Mathf.Sin((t) * angle) * division;
       return new Quaternion(
           p.x*t0 + q.x * t1,
           p.y*t0 + q.y * t1,
           p.z*t0 + q.z * t1,
           p.w*t0 + q.w * t1
       );
   }

Note that I currently can't test this method as I don't have Unity at hand. I can also not guarantee that it works as I haven't verified the original method, but it looks right. My version is just a simplification / inlining of the original post. It reduces the method calls and also the required multiplications

avatar image krisventure · Mar 18, 2021 at 11:04 PM 0
Share

Imagine if Unity made it easy for us and added this solution and all you'd have to do is to set an additional bool param, wouldn't that be awesome ... I've had to look up this issue so many times over the years and always ended up implementing some length workaround.

avatar image
0

Answer by wolfgraphicsLLC · Jan 28, 2021 at 07:06 PM

ok @FreetimeCoder i know of at least 2 ways to fix that off the top of my head first as a dev not as a just programmer how is your object set up wat does the scenario look like in the scene view and as well the inspector setting s and setup in hierarchy cold you either upload a sort video or a couple screen shots showing this? or another option is you could go to discord to https://discord.gg/gjWDxcPC and go to the programing and general unity channel and @ john nic?9wolfgraphicsllc) that's me I am one of the tutors and moderators there as well there is a create a ticket channel where you can get a little more focused assistance. and i would be glad to look it over and walk you through and trouble shoot it with you for like i always say when it comes to dev work and coding alike there is always more than one way to skinn a cat

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

19 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

Related Questions

Drawing a path - rotation of corner textures 1 Answer

Tilt aircraft based on accelerometer 0 Answers

Make a drunk character swerve and loop on the way to a waypoint but still make it eventually. 2 Answers

iTweens MoveTo and "path" property 7 Answers

iPhone/iOS File URLs 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