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 SocketPop · Jun 03, 2015 at 06:45 PM · rotationquaternionlerp

How can I Lerp a rotation through "straight up?"

I have a spaceship object with a transform. A second transform is positioned some offset distance away, and then I use LookAt() to aim its forward vector at the ship. The ship's parent is this second transform. To move the ship, I take player input to place a destination object on the sphere. I create a "destination" transform at the center of the sphere, and use Lerp() or RotateTowards() to move the ship over the surface of the sphere, from the player's rotation to the destination rotation.

 parentTransform.rotation = Quaternion.Lerp(parentTransform.rotation,
      destinationTransform.rotation, Time.deltaTime * speed);

The problem I'm having is when the parent transform needs to Lerp "through the north pole" (or south pole.) Since the forward vector is aimed at the player ship, this trouble spot is when the forward vector is trying to point either straight up or straight down.

Instead of my ship flying smoothly over the pole to arrive at his destination on the other side, he instead rotates around the north pole, and ends up on the other side facing backwards. I have managed to get the ship stuck at the north pole, but flying across it has never worked for me, and all of my attempted solutions have ended in disaster.

alt text

My question is, how can I get the desired behavior here? My hope is that this is a known issue with Lerp() and there's an elegant workaround. Any help is appreciated!

northpole.jpg (156.5 kB)
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
Best Answer

Answer by neonblitzer · Jun 03, 2015 at 07:06 PM

The lerping probably works as intended. The problem is that you create the rotations with LookAt, and the relative up axis is very close to the ship's or target's position which makes small differences in direction affect resulting rotation greatly. You should specify the worldUp parameter in Transform.LookAt to be as far away as possible from the ship's and target's positions. You can use, for example, a cross product of the vectors to the ship and the destination to acquire a vector that is at right angle to (90 degrees away from) both of them, and use that as the worldUp parameter in LookAt to create the start and end rotations.

...Pretty hard to explain. Please comment if it's still unclear :)

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 AlwaysSunny · Jun 03, 2015 at 07:08 PM 0
Share

Excellent point. I totally forgot he was using LookAt to find his target rotation. I'd be willing to bet that would solve his problem!

avatar image neonblitzer · Jun 03, 2015 at 07:16 PM 0
Share

Thanks :) @SocketPop, check out my comment on Sunny's answer too. You might want to rethink your approach, depending on your needs.

avatar image SocketPop · Jun 04, 2015 at 01:24 AM 1
Share

Brilliant, thank you so much for this solution. It worked beautifully! Here's a code snippet slightly modified to be clearer, showing how I got it to work with your suggestion.

 // Given playerObject (this) and destObject, which have parent
 // transforms playerParent and destParent...
 
 // Get the cross product of the two vectors.
 Vector3 upVector = Vector3.Cross(playerParent.forward,
      destParent.forward);
 
 // Decouple playerObject and destObject transforms from 
 // their parents. Otherwise, they would be rotated in an
 // undesirable way by the upco$$anonymous$$g LookAt()
 transform.parent = null;
 destObject.transform.parent = null;
 
 // The parent transforms (positioned at the center of the sphere)
 // LookAt the two objects again, but with .up perpendicular
 playerParent.LookAt(transform.position, upVector);
 destParent.LookAt(destObject.transform.position, upVector);
 
 // Reunite playerObject and destObject with their parents.
 // So the objects will rotate with the upco$$anonymous$$g Lerp
 transform.parent = playerParent;
 destObject.transform.parent = destParent;
 
 playerParent.rotation = Quaternion.Lerp(playerParent.rotation,
      destParent.rotation, Time.deltaTime * speed);

And yes, after posting this question I then tried a different approach which did not rely on Lerp(). It's not done yet, but if successful I'll post my results here. Thanks again! Even if my alternate approach works, I bet this quirk with Lerp() will come up again and next time I'll be ready!

avatar image
0

Answer by AlwaysSunny · Jun 03, 2015 at 07:02 PM

Frankly, I don't follow. I feel like maybe all the necessary information is here to form a clear picture, but it's not translating into a concrete understanding for me. I know it's hard to describe complex scenarios.

A Lerp is a linear interpolation from one quaternion value set to another. It isn't broken or limited in certain conditions; it does exactly what it's supposed to do. The problem must lie in your utilization. In your defense, this stuff can be very confusing.

If I'm understanding, your ship's movement about the surface of a sphere is achieved by rotating the ship around the sphere's origin.

I guess that all makes sense and ought to work, but the problem you are describing does not seem directly related to the selected approach. It also seems like you aren't actually achieving what you're hoping to achieve in the first place. If logic creates an unwanted change in one scenario, it's probably creating the same kind of not-quite-right change in other scenarios, you just aren't noticing. Any chance you're certain I'm wrong, and it only acts funny at the poles?

My first thought is this: You are wanting to achieve this behavior using only a target rotation. That target rotation does not - on its own - represent enough information to give you the results you're seeking.

I would first try to rely on a different method for making the ship "face" the desired destination. Remove that element from the equation altogether and get there in some other way. Besides, to look correct and "hug" the surface, the ship needs to face a direction tangential to the arc described by its motion.

My other thought is this: You may be using an improper method for arriving at the unknown (destinationTransform.rotation) which drives this behavior.

Quaternion representations and extensions are designed for exactly this kind of complex situation. No gimbal lock, no weird edge cases - if you're using them properly, this kind of problem does not manifest.

Comment
Add comment · 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 neonblitzer · Jun 03, 2015 at 07:12 PM 0
Share

The target rotation does have enough information, I think. It's just that now the rotations represent both the ships' position and local rotation, so you have to be very exact and careful when creating the rotations. And eventually the two are going to un-sync no matter how careful you are :)

As you suggested, it might be easier in the long run to have the lerping only control the position and orient the ships with a completely different method separately. It enables them to face other directions when moving, for example.

avatar image AlwaysSunny · Jun 03, 2015 at 07:20 PM 0
Share

$$anonymous$$arked your answer as correct; realizing how he was getting his target rotation, I'm quite confident injecting a valid normal axis in the LookAt() is gonna fix his problem.

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

How can I smooth the rotation using quaternion and raycast? 1 Answer

Smoothly Rotate 2D sprite 90 degrees on click 2 Answers

Lerping Quaternions Results in NaN's 1 Answer

better way to rotate instead Coroutine 1 Answer

Use Lerp to rotate 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