Rotating GameObject to smoothly face position

I have a feeling this has been asked, but I’ve been through these forums a few times and tried a few things, but have had no luck so far.

So I have a character who uses the navMesh in unity pro to move to a position. That’s fine. Once he gets there, I want to give him a command to face a specific direction (locking z so he doesn’t end up leaning back in the world).

I started with transform.LookAt which functionally did what I want, but it’s a quick snap to and not what I want to have in the end.

So then I tried the following snippet:

(targetFacing is the object to face to)

float dx = transform.position.x - targetFacing.transform.position.x;
            float dz = transform.position.z - targetFacing.transform.position.z;

            float radians = Mathf.Atan2(dz, dx);
            float angle = radians * 180 / Mathf.PI;

            float rotateY = Mathf.LerpAngle(transform.position.y, angle, Time.time/2);

            transform.eulerAngles = new Vector3(targetFacing.transform.rotation.x, rotateY, targetFacing.transform.rotation.z);

            if((rotateY + transform.eulerAngles.y) >= 180){
                Debug.Log ("Facing");
                targetFacing = null;
            }

The problem with this was depending on where targetFacing was in relation to his stop point, he would 3 out of 4 times face the target, but would sometimes face away, or at a 90 degree angle.

For example, if the target was north, south or east, he would face it, but if it was west, he would face away. I played with the angle to be radians * 180/Mathf.PI+90, -90, +180, etc but it always ended up with him facing it most of the time, but on occassion not.

So then I tried this:

strength being a float.

Quaternion targetRotation = Quaternion.LookRotation(targetFacing.transform.position - this.transform.position);
            strength = Mathf.Min(strength * Time.deltaTime, 1);
            this.transform.rotation = Quaternion.Lerp(this.transform.rotation, targetRotation, strength);

In a function called on LateUpdate (controlled via a bool), but that doesn’t seem to do anything at all.

I’m pulling my hair out on this one, can anyone help?

Ok, I’m almost there - I played with the second solution a little more and got this:

Quaternion rotateDirection = Quaternion.LookRotation(targetFacing.transform.position - this.transform.position);
            this.transform.rotation = Quaternion.Lerp(this.transform.rotation, rotateDirection, turnSpeed*Time.deltaTime);

Which has it rotating (It seems) properly, I just need to figure out a way to determine when it’s facing the direction since the object’s transform.rotation doesn’t QUITE match up with rotateDirection.

using UnityEngine;
using System.Collections;

public class CameraFollow : MonoBehaviour {
    public Transform player;
    public float smoothrate = 0.5f;
    private Transform thisTransform;
    private Vector3 velocity;
    void Start()
    {
        thisTransform = transform;
        velocity = new Vector3 (0.5f, 0.5f, 0.5f);
    }

    void  Update ()
    {

//Our new position in 3d world space
        Vector3 newPos3D = Vector3.zero;
        newPos3D.x = Mathf.SmoothDamp (thisTransform.position.x, player.position.x, ref velocity.x, smoothrate);

        newPos3D.y = Mathf.SmoothDamp (thisTransform.position.y, player.position.y / 1.2f, ref velocity.y, smoothrate);


//Your target to look at.
        Vector3 newPos = new Vector3 (newPos3D.x, newPos3D.y, transform.position.z);
        transform.position = Vector3.Slerp (transform.position, newPos, Time.time);
    }
  
} [code]
Quaternion rotateDirection = Quaternion.LookRotation(targetFacing.transform.position - this.transform.position);
transform.rotation = Quaternion.RotateTowards(transform.rotation, rotateDirection, 5 * Time.deltaTime);

you can use Unity - Scripting API: Quaternion.Angle to determine if angles are the same

Thanks for the help, all - got it working with sort of a bastard-ized version of all of the above :slight_smile: