Smooth look at

How can I make a smooth rotate to object?

this is the code that i’m using

var localizeobject : Transform; 
var localize = false;

function Update () {
if (localize == true){
transform.LookAt(localizeobject);
localize = false;
}
else
{
}
}

function OnGUI () {
	if (GUI.Button (Rect (10,100,150,100), "Localize Object")) {
		localize = true;
	}
}

This causes a instant rotation to the object… how can i make this rotation smooth?

try this:

var targetObj : GameObject;
var speed : int = 5;

function Update(){
var targetRotation = Quaternion.LookRotation(targetObj.transform.position - transform.position);
       
// Smoothly rotate towards the target point.
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}

:wink:

48 Likes

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.

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.

Works Like a Charm (Unity 5.5.2)

1 Like

public GameObject targetObj;
public int = 5;

void Update()
{
Quaternion targetRotation = Quaternion.LookRotation(targetObj.transform.position - transform.position);

// Smoothly rotate towards the target point.
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}

4 Likes

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)

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

IEnumerator RotateTransform(float dur)
       float t = 0f;
       while(t < dur){
              t += Time.deltaTime;
              float factor = t / dur;//use this for lerping
              yield return null;//basically wait for next frame
        }
        print("Rotation Finished");
}

This still works! Thanks a lot!

what can i use to limit rotation on the smooth look at script??

I think the answer provided in the 2nd post is not correct.

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.

This worked well for me
Thanks for sharing

2021 and still relevant! thank you!

2 Likes

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.

12 years later you are still a genious

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:

        public Transform target;
        public float speed;

        private Quaternion targetRotation;
        private Quaternion startRotation;
        private bool cached;

        private void CacheStartOnceBefore()
        {
            if (cached) return;

            targetRotation = Quaternion.LookRotation(target.position - transform.position);
            startRotation = transform.rotation;
            cached = true;
        }

        private void FixedUpdate()
        {
            CacheStartOnceBefore();

            transform.rotation = Quaternion.Slerp(startRotation, targetRotation, speed * Time.fixedTime);
        }

Or you can use RotateTowards:

       Vector3 targetDir = target.position - transform.position;
       targetDir.y = 0.0f;
       transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(targetDir), Time.deltaTime* speed );
5 Likes

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.

1 Like

how is that post even supposed to help?

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.

It has zero value.

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

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.