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
1
Question by Anymeese · Aug 06, 2014 at 03:25 AM · rotationtransformquaternionlerpsmooth

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

I know Linear Interpolation slows down the ends because that's just how it works. However I'm trying to make a character turn to face a point over the course of roughly 0.33 seconds.

I've tried using normalize, Math.smothStep, Lerp, Slerp, Vector3.MoveTo, etc. I have googled this and tried many things but everything has an issue. Some have the smoothing at ends, others are not accurate enough, fast enough, slow enough, etc.

I just want to make my character smoothly rotate and look at a point at a consistent speed

My code right now, in Update() (that slows the ending):

 float speed = 5f;
 Quaternion rotationToLookAtNode = Quaternion.LookRotation(node.transform.position - this.gameObject.transform.position);
 transform.rotation = Quaternion.Lerp(transform.rotation, rotationToLookAtNode, speed * Time.deltaTime);
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 robertbu · Aug 06, 2014 at 05:59 AM 1
Share

To get constant speed, change final line of your code above to:

   transform.rotation = Quaternion.RotateTowards(transform.rotation, rotationToLookAtNode, speed * Time.deltaTime);

'speed' will then be degrees per second, and you will not get the slowing as you would have with Lerp() or Slerp()...and no need for a timer.

avatar image Reedex robertbu · Jun 10, 2018 at 09:31 AM 0
Share

nice , i'll give it a go . thanks should be answer too shouldn it,... :P quite some time, you still alive ?::)))

3 Replies

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

Answer by Loius · Aug 06, 2014 at 03:45 AM

Slerp (Lerp) from a rotation to a target rotation. What you're doing is rotating from the current rotation to the target rotation, which is constantly getting smaller as you get closer. You need to record the rotation at the time you initiated the rotation, and modify the third argument so it goes 0-1.

 IEnumerator RotateTo(Quaternion target) {
   Quaternion from = transform.rotation;
   for ( float t = 0f; t < 1f; t+= speed*Time.deltaTime ) {
     transform.rotation = Quaterion.Lerp(from,target,t);
     yield return null;
   }
   transform.rotation = target;
 }

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 Anymeese · Aug 06, 2014 at 05:47 AM 0
Share

Works almost perfectly, thank you! The only thing that isnt perfect is that this makes it take the same duration to turn, whether turning 10 degrees or 180. So when the unit has to turn completely around, it goes really fast, but if only turning a little, is pretty slow. Is there an easy way to make the turning speed consistent?

avatar image Loius · Aug 07, 2014 at 04:49 PM 2
Share

You want the object to rotate at "X" degrees per second, so just find how many degrees between target and from and mathify it.

I have no idea if it's easy to find the difference in quaternions. If you use Vector3's for target and from you can just say float degrees = (target - from).magnitude. You can convert the v3's to Quaternion with "Quaternion.Euler(v3)".

The total time of the turn is float totalTime = degrees/degreesPerSecond.

So your final for-loop would look like this:

for ( float t = 0f; t < 1f; t+= Time.deltaTime / totalTime ) {

avatar image Anymeese · Aug 07, 2014 at 07:55 PM 1
Share

Works like a charm! Thank you very much :)

To do it with Quaternions, I just converted them to EulerAngles/Vector3s like so:

 float degreesToTurn = (Quaternion.ToEulerAngles(to) - Quaternion.ToEulerAngles(from)).magnitude;
avatar image
2

Answer by supernat · Aug 06, 2014 at 03:47 AM

Since you are performing the lerp every frame from the current value (transform.rotation), you will be acting on a distance that is shrinking every frame, so you will indeed see the rotation slow as you get closer to the end, because the value you are passing to the sleep for the amount (the speed) will be constant for the most part (yes not really, but it is very close as long as all of your frames are about the same time apart). So let's just assume this rate * time.deltaTime is about 0.5 for simplicity. In the first frame, you slerp to 50% of the full rotation. In the second frame, you slerp 50% of What Remains in the rotation, so you can see as frames continue, you continue to slerp 50%, but the rotation amount becomes smaller and smaller.

To fix this, capture the starting rotation at the beginning and use that as the first parameter every frame. Also, simply slerp from 0.0 to 1.0, which is actually the intended use of the lerp and slerp methods, though many people use them in the way you have to ease in and out, which you don't want. So, in frame 1, pass in 0.0, in frame 2, pass in 0.1, in frame 3, 0.2, etc. for the third parameter to lerp. Also, I would do this in the FixedUpdate, though not necessary, but if you do it in Update, it would require the time.deltaTime correction, so you would increase the third parameter by say rate * time.deltaTime every frame, limiting it to 1.0, where rate is around 2 if you wanted the rotation to be about 3% every frame at 60 hz.

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 MagyarPeter · Mar 03 at 05:13 PM

I use this code for homing projecties:

  public float rotationSpeed = 200f;
  public float speed = 20f;
     public Transform followMe;
     void FixedUpdate()
     {
         Quaternion q = new Quaternion();
         q.SetLookRotation(followMe.position - transform.position);
         transform.rotation = Quaternion.Slerp(transform.rotation,q, 1f / Quaternion.Angle(transform.rotation, q) * Time.fixedDeltaTime * rotationSpeed);
         transform.position += transform.rotation * Vector3.forward * speed * Time.fixedDeltaTime;
     }
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

25 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

Related Questions

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

Smoothing the characters rotation with Lerp 2 Answers

How would I smooth out a Quaternion? 2 Answers

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

How to smoothly rotate to certain directions using input axis 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