Search Unity

Smooth look at

Discussion in 'Scripting' started by radiolobito, Jul 7, 2009.

  1. radiolobito

    radiolobito

    Joined:
    Jun 12, 2009
    Posts:
    117
    How can I make a smooth rotate to object?

    this is the code that i'm using

    Code (csharp):
    1. var localizeobject : Transform;
    2. var localize = false;
    3.  
    4. function Update () {
    5. if (localize == true){
    6. transform.LookAt(localizeobject);
    7. localize = false;
    8. }
    9. else
    10. {
    11. }
    12. }
    13.  
    14. function OnGUI () {
    15.     if (GUI.Button (Rect (10,100,150,100), "Localize Object")) {
    16.         localize = true;
    17.     }
    18. }
    This causes a instant rotation to the object... how can i make this rotation smooth?
     
  2. jaxas

    jaxas

    Joined:
    Mar 22, 2009
    Posts:
    59
    try this:
    Code (csharp):
    1.  
    2. var targetObj : GameObject;
    3. var speed : int = 5;
    4.  
    5. function Update(){
    6. var targetRotation = Quaternion.LookRotation(targetObj.transform.position - transform.position);
    7.        
    8. // Smoothly rotate towards the target point.
    9. transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
    10. }
    11.  
    ;)
     
  3. Ineno

    Ineno

    Joined:
    Jul 7, 2009
    Posts:
    2
    Do you have a smart way of detecting if the camera finished the movement? So that I can take away control of the camera while it's doing the smooth look at but give it back once it's done looking at that certain object.
     
  4. radiolobito

    radiolobito

    Joined:
    Jun 12, 2009
    Posts:
    117
    It's workin great!

    I think this is a great solution, I'm agree with Ineno; i need to know when the rotation finish to stop this automatic rotation and make the manual rotation again.
     
  5. ieselisra

    ieselisra

    Joined:
    Nov 6, 2015
    Posts:
    1
    Works Like a Charm (Unity 5.5.2)
     
    angelomoro likes this.
  6. WalterEspinar

    WalterEspinar

    Joined:
    Aug 23, 2011
    Posts:
    84
    1. Code (CSharp):
      1. public GameObject targetObj;
      2. public int = 5;
      3.  
      4. void Update()
      5. {
      6. Quaternion targetRotation = Quaternion.LookRotation(targetObj.transform.position - transform.position);
      7.      
      8. // Smoothly rotate towards the target point.
      9. transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
      10. }
     
    rc82, DarkSlashHero and Luis_Gan like this.
  7. riboslem_unity

    riboslem_unity

    Joined:
    Oct 25, 2018
    Posts:
    1
    you can use a raycast to determine if you are pointing to the desired object and so to know if the rotation is finished (maybe wait 0.2s (depends of the rotation speed) to let it looks at the center of the object)
     
  8. b_v_

    b_v_

    Joined:
    Feb 16, 2018
    Posts:
    4
    I think I am pretty late maybe, but instead of raycast, u can turn this into a coroutine and then know if it has finished, something like this

    Code (CSharp):
    1. IEnumerator RotateTransform(float dur)
    2.        float t = 0f;
    3.        while(t < dur){
    4.               t += Time.deltaTime;
    5.               float factor = t / dur;//use this for lerping
    6.               yield return null;//basically wait for next frame
    7.         }
    8.         print("Rotation Finished");
    9. }
     
  9. DranrebKing

    DranrebKing

    Joined:
    Jun 3, 2018
    Posts:
    4
    This still works! Thanks a lot!
     
  10. silvabrid_unity

    silvabrid_unity

    Joined:
    Nov 14, 2019
    Posts:
    1
    what can i use to limit rotation on the smooth look at script??
     
  11. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    I think the answer provided in the 2nd post is not correct.

    Code (CSharp):
    1. transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
    If I'm not mistaken (and I could be!!), this will never actually resolve. The 3rd parameter should be between 0 and 1, where 0 will return transform.rotation and 1 will return targetRotation.
     
  12. Arcadian-Unity

    Arcadian-Unity

    Joined:
    Mar 14, 2020
    Posts:
    4
    This worked well for me
    Thanks for sharing
     
  13. yonatanab1

    yonatanab1

    Joined:
    Sep 9, 2018
    Posts:
    56
    2021 and still relevant! thank you!
     
    RenanRL and mjunaidch like this.
  14. StuGrimson

    StuGrimson

    Joined:
    Nov 10, 2021
    Posts:
    1
    Anyone have a clever way of returning the LookAt control smoothly back to an animation clip that was running? I've got a scenario where an animated rigged object needs to have the LookAt relinquished without snapping back to the looping animation that was controlling the bone to start. So far, I don't see a way of reading the clip's key values at runtime. Maybe a potential way of creating another state to transition to, but the SetLookAtPosition is only for humanoid rigs afaik. Any ideas? It would great if the LookAt function had a weight to it, like the SetLookAtPosition has available.
     
  15. Jandru1

    Jandru1

    Joined:
    May 5, 2021
    Posts:
    1
    12 years later you are still a genious
     
  16. razzraziel

    razzraziel

    Joined:
    Sep 13, 2018
    Posts:
    396
    That is not a linear movement tho. It'll get slower and slower at the end because it is always lerping (slerping in this case) with percentage and it is modifying the start position constantly. Also it is better to do these stuff in FixedUpdate.

    You can either use a temporary rotation variable:
    Code (CSharp):
    1.  
    2.         public Transform target;
    3.         public float speed;
    4.  
    5.         private Quaternion targetRotation;
    6.         private Quaternion startRotation;
    7.         private bool cached;
    8.  
    9.         private void CacheStartOnceBefore()
    10.         {
    11.             if (cached) return;
    12.  
    13.             targetRotation = Quaternion.LookRotation(target.position - transform.position);
    14.             startRotation = transform.rotation;
    15.             cached = true;
    16.         }
    17.  
    18.         private void FixedUpdate()
    19.         {
    20.             CacheStartOnceBefore();
    21.  
    22.             transform.rotation = Quaternion.Slerp(startRotation, targetRotation, speed * Time.fixedTime);
    23.         }
    24.  
    Or you can use RotateTowards:
    Code (CSharp):
    1.  
    2.        Vector3 targetDir = target.position - transform.position;
    3.        targetDir.y = 0.0f;
    4.        transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(targetDir), Time.deltaTime* speed );
    5.  
     
    SkylorBeck, merpheus and yonatanab1 like this.
  17. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,741
    Stop using Lerps (or Slerps, or whatever) with speed * Time.deltaTime or whatever, for movement or rotation. It is a horrible thing and will behave differently depending on framerate, don't do it.

    This isn't the the way to use interpolation, no matter what Unity tells you, they also don't know any better.
     
    khaled24 likes this.
  18. razzraziel

    razzraziel

    Joined:
    Sep 13, 2018
    Posts:
    396
    how is that post even supposed to help?
     
  19. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,741
    It's a note, on a really old thread with really old advice that has people calling the original solution genius.

    The note is : "this solution is bad, please look elsewhere" and it's supposed to urge people to research this further (and stay away from Unity's tutorial's, since they do this themselves and are a big reason why people keep misusing lerps).

    I think that has value of being in this thread.

    You obviously don't, demonstrated by your misquoting me, but I don't think that's my fault.
     
  20. razzraziel

    razzraziel

    Joined:
    Sep 13, 2018
    Posts:
    396
    It has zero value.

    You're not pointing to anything. What is the alternative?
    https://www.google.com/search?q=unity lerp alternative

    These guys thanking for an example use for Slerp. A basic Unity method openly available in docs. Think about that.

    I didn't misquoted you, that is exactly what it is.
     
  21. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,741
    If you want to drink bleach, surely I can say "don't drink bleach" without having to provide alternative things to drink.

    And I didn't say don't use Lerp and Slerp, I said don't use it with things like speed * Time.deltaTime, as that makes the results framerate dependent. Maybe that wasn't clear in my original post, or you were too busy misquoting me to notice.

    https://www.google.com/search?q=time+deltatime+lerp
     
  22. razzraziel

    razzraziel

    Joined:
    Sep 13, 2018
    Posts:
    396
    That is not a bleach, that is still water in a plastic bottle that everyone drinks from and told to do so by government. And you're saying hey don't drink that.

    The whole point was about your post that wasn't pointing to anything. And that was a good example to show that.

    Anyways, isn't deltatime supposed to make it frame independent? Or am I missing something here?
     
    rc82 likes this.
  23. yonatanab1

    yonatanab1

    Joined:
    Sep 9, 2018
    Posts:
    56
    literaly a king ^
     
  24. LudumCor

    LudumCor

    Joined:
    Nov 11, 2016
    Posts:
    8
    As AcidArrow pointed out! You should not use speed * Time.deltaTime as the t value of Lerp/Slerp functions!
    The problem is that you may never reach the final rotation/position in this way, and your framerate will also significantly affect the speed.

    I'll try to make a clear example:
    Let's say you want to go from Point A to Point B, and your game runs at 60 frames per second, equivalent to a 0.016666 deltaTime. For simplicity, let's use speed = 30.

    In the first frame, you will move from Point A toward Point B about t = 0.5 (0.016666 * 30), right in the middle between the two points, which will become your new Point A.

    Agin, next frame, you will also move right in the middle between your current Point A and Point B.

    As you can see, you are just reducing the distance between you and your final target at each frame, not really reaching it. And that's considering a constant target frame rate in every device you plan to use.

    Side note: You will eventually reach Point B because you reached the minimum float precision, and the value snaps to the target.

    There are many ways to fix this problem:

    One way is to add speed * Time.deltaTime to t (initially set at 0) and use a saved initial value of Point A and B.
     
  25. MathewHI

    MathewHI

    Joined:
    Mar 29, 2016
    Posts:
    501
    The Unity Manual specifically states Time.deltatime is framerate independent.
     
  26. MathewHI

    MathewHI

    Joined:
    Mar 29, 2016
    Posts:
    501
    How do you make RotateTowards start and stop more smoothly? It starts and stops too abruptly.
     
  27. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,741
    Link? Because this statement couldn't be more wrong.

    Time.deltaTime is completely frame rate dependant, meaning that its value directly depends on the frame rate.

    What you probably mean is that you can use Time.deltaTime to make things frame rate independent, but that DOES NOT MEAN you can just shove Time.deltaTime into any function without thinking and it magically makes your math framerate independent.
     
  28. MathewHI

    MathewHI

    Joined:
    Mar 29, 2016
    Posts:
    501
    My mistake, thank you for kicking me in the pants and setting me straight sir.