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 Leroterr · May 30, 2014 at 12:37 AM · rotationtransformquaternionlerpeulerangles

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

How do you smoothly transition or lerp a rotation of an object to a new rotation?

My direction changes every time the player presses a button. But when it does, the rotation gets changed immediately, with no transition whatsoever.

Is there a way I can do this?

Here's the script I'm using, it's pretty straight forward and simple:

 GameObject.FindWithTag("Player").transform.eulerAngles = rot;
 
 rot = new Vector3 (direction.y * 100, 0, direction.z * 100);

I just couldn't find a way to smoothly transition Player's eulerAngles to rot since I'm pretty new to Unity and C# itself.


Vector3.Lerp doesn't seem to work as well with it. It flips out and have no idea why. Here's the script I made for it:

 GameObject.FindWithTag("Player").transform.eulerAngles = Vector3.Lerp(Vector3.zero, rot, Time.deltaTime * 5);

With this one, for some reason, the rotation just keeps going back and forth. For example, when I'm pressing the right button, it rotates to right, goes back to Zero, then rotates back to right again, then rotates back to Zero, then rotates back to the right again... at a somewhat fast rate until I let go of the right button.

Maybe I did something wrong with it.

Thanks to anyone who can help :)

Comment
Add comment · Show 2
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 Slvr99 · May 30, 2014 at 12:45 AM 0
Share

Try this:

 GameObject.FindWithTag("Player").transform.eulerAngles = Vector3.Lerp(GameObject.FindWithTag("Player").transform.eulerAngles, rot, Time.deltaTime * 5);
avatar image DMGregory · May 30, 2014 at 12:47 AM 1
Share

Every time you lerp with Euler angles, a fairy experiences Gimbal Lock.

3 Replies

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

Answer by DMGregory · May 30, 2014 at 12:46 AM

Euler angles are okay for data entry, but lousy for interpolation.

For example, if you wanted to blend between Euler angles (0, 0, 0) and (0, 359, 0), the shortest path is to rotate -1 degrees around the y-axis. But interpolating the two vectors will have your object spin around the long way, +359 degrees.

Euler angles also exhibit gimbal lock and other interactions between the rotation axes, so when you try to interpolate rotation on multiple axes at once the object can appear to lurch and tumble from one rotation to another, instead of performing one smooth continuous rotation. Vector3.Slerp won't help here, at least not directly, because it's for interpolating vectors representing spatial directions, not Euler angles.

Quaternion methods solve all of this automatically, because they don't experience gimbal lock or 0/360 wrap-around issues.

Quaternions vs Euler

Here you can see the same rotation interpolated with Quaternions (left, smooth & predictable) and Euler angles (right, object tumbles along its long axis during the turn) (Source and Interactive Demo)

Working with quaternions in Unity is easy thanks to convenience methods like Quaternion.RotateTowards, which you can use something like this:

 // Maximum turn rate in degrees per second.
 public float turningRate = 30f; 

 // Rotation we should blend towards.
 private Quaternion _targetRotation = Quaternion.identity;

 // Call this when you want to turn the object smoothly.
 public void SetBlendedEulerAngles(Vector3 angles)
 {
   _targetRotation = Quaternion.Euler(angles);
 }
 
 private void Update()
 {
    // Turn towards our target rotation.
    transform.rotation = Quaternion.RotateTowards(transform.rotation, _targetRotation, turningRate * Time.deltaTime);
 }

This will give you a smooth rotation toward your target orientation, from any starting orientation, at a constant rate of rotation. Note that you can still provide your target orientation using Euler angles, and we can convert that input to an intermediate quaternion representation with one line.

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 neomarian · Apr 23, 2017 at 05:12 PM 1
Share

There is a problem with this approach: I tried to rotate an object from (250, 180, 0) to (260, 180, 0) and I used Quaternions as in your example but the result was (260, 0, 180) which was not same as (260, 180, 0)...because the object pivot is not the same as the object center.

avatar image Sungold · Jul 26, 2017 at 07:01 PM 0
Share

The little quaternion demonstration game you made is fascinating. Thank you very much for this work!

avatar image
5

Answer by rutter · May 30, 2014 at 12:51 AM

The first problem is that you're using Lerp incorrectly.

Lerp, short for “linear interpolation” does one very simple thing: given two values, x and y, it returns a value that is t percent between them. If you expect the output to change, the arguments you pass in need to reflect that!

It doesn’t make sense to just pass in Time.deltaTime, because that’s only the time that passed during the most recent frame. If your game is running at a constant 50fps, that’s always going to be 0.02.

You need to pass in a value that changes over time.

Suppose we create two variables:

  • lerpTime is the number of seconds we want the Lerp to take.

  • currentLerpTime is the number of seconds since we started the Lerp.

When we start the Lerp, we could set lerpTime to 5 and currentLerpTime to 0:

 lerpTime = 5;
 currentLerpTime = 0;

We can increase currentLerpTime by Time.deltaTime once per frame:

 //in Update()
 currentLerpTime += Time.deltaTime;

Then, we Lerp like this:

 Vector3 result = Vector3.Lerp(a, b, currentLerpTime / lerpTime);

Second, if you're able to, you might consider using Slerp, instead. If Euler angles are working for you, go ahead and use them. There are a few corner cases where they have limits, though.

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

Answer by davidnibi · Nov 03, 2019 at 07:21 PM

 Quaternion.RotateTowards(<existing rotation>, <new rotation>, ...

So simple! I was doing this through about 5 lines! And I was putting off fixing this for a while!

I've translated between a predefined 'light sway' effect on trees (under normal conditions), to a violent effect in a storm!

         {
             Quaternion newEulerAngle = Quaternion.Euler(finalAngleX + xRotationOffset, finalAngleY + yRotationOffset, finalAngleZ); //Apply new angle to object
 
             transform.rotation = Quaternion.RotateTowards(transform.rotation, newEulerAngle, turningRate * Time.deltaTime);

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

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

Related Questions

How to rotate 90 degrees from 270 degrees to 0 with lerp? c# 1 Answer

Camera viewport transformation from one world to the rotated world. 1 Answer

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

Unity Quaternion Problem (Should be A Bug?) 1 Answer

Problem about Rotating the Character 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