0
\$\begingroup\$

The goal is to make smooth rotating look at.

The parent object is my character have a Rigidbody.

The script is attached to the character parent. I make a reference to the character child name head.

I have a cube as the target the cube is rotating around the character with random height.

The character is never looking at the cube. I tried to change from LateUpdate to Update I tried to add a child of the head empty gameobject and reference the empty gameobject but still the character head is not rotating to the target.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmoothLookAt : MonoBehaviour
{
    public Transform leadObj;
    public Transform lookAtTarget;
    public float damping = 6;
    public bool smooth = true;


    private void LateUpdate()
    {
        if (lookAtTarget)
        {
            if (smooth)
            {
                // Look at and dampen the rotation
                var rotation = Quaternion.LookRotation(lookAtTarget.position - leadObj.position);
                leadObj.rotation = Quaternion.Slerp(leadObj.rotation, rotation, Time.deltaTime * damping);
            }
            else
            {
                // Just lookat
                leadObj.LookAt(lookAtTarget);
            }
        }
    }

    private void Start()
    {
        // Make the rigid body not change rotation
        if (leadObj.GetComponent<Rigidbody>() != null)
            leadObj.GetComponent<Rigidbody>().freezeRotation = true;
    }
}

It seems to be working if I reference the head directly as leadObj and inside LateUpdate the problem is that I have to set the damping value to 260.

Why I need to set the damping value to be so high ?

And how can I make that the head will rotate to the target with automatic speed depending on the target moving speed ? So if I don't set any damping value for example 0 or null it will automatic calculate the needing speed to rotate facing the target ?

I see now another problem. If I set the damping value to 100 for example the character head is stuttering the head will look at the target but will stuttering. I want that if the damping value is 100 or lower than rotate the leadObj with a delay facing the target. Something like when a turret is rotating facing a missile and if the missile is moving too fast the turret is rotating with some delay because he rotate slower. How can I do it ?

This is working using Lerp. But why if I set for example the duration value to 0 it's not affecting the speed of the leadObj rotation ?

The leadObj keep rotating same speed facing the target even if the duration is 0.

What am I missing ?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmoothLookAt : MonoBehaviour
{
    public Transform leadObj;
    public Transform lookAtTarget;
    public float duration;
    public bool smooth = true;

    private float t = 0.0f;

    private void Start()
    {
        // Make the rigid body not change rotation
        if (leadObj.GetComponent<Rigidbody>() != null)
            leadObj.GetComponent<Rigidbody>().freezeRotation = true;
    }

    private void LateUpdate()
    {
        if (lookAtTarget)
        {
            if (smooth)
            {
                t += Time.deltaTime;
                float s = t / duration;

                // Look at and dampen the rotation
                var rotation = Quaternion.LookRotation(lookAtTarget.position - leadObj.position);
                leadObj.rotation = Quaternion.Lerp(leadObj.rotation, rotation, s);
            }
            else
            {
                // Just lookat
                leadObj.LookAt(lookAtTarget);
            }
        }
    } 
}
\$\endgroup\$
5
  • 2
    \$\begingroup\$ "Why I need to set the damping value to be so high ?" because your code is incorrect. This is not the way to adjust a lerp or slerp for delta time, and it's not beneficial to use slerp over lerp when you're using a non-linear easing function anyway. \$\endgroup\$
    – DMGregory
    Sep 9, 2021 at 18:54
  • \$\begingroup\$ Than what should I use in this case instead slerp/lerp ? Just using rotatetowards ? \$\endgroup\$
    – Daniel Lip
    Sep 9, 2021 at 18:59
  • 1
    \$\begingroup\$ I did not suggest avoiding lerp. \$\endgroup\$
    – DMGregory
    Sep 9, 2021 at 19:01
  • \$\begingroup\$ Updated in my question a working code with Lerp but I still don't understand if I set the duration value to 0 how come the leadObj is keep rotating looking at the target ? Isn't the leadObj should stop rotating ? \$\endgroup\$
    – Daniel Lip
    Sep 9, 2021 at 19:28
  • 1
    \$\begingroup\$ You did not correctly implement either of the two versions of lerp demonstrated in my answer. You've mashed them up into a hybrid that achieves neither the goals of the linear lerp nor the goals of the exponential ease out. I would recommend re-reading what I wrote, to ensure you understand what the math is doing at each step. \$\endgroup\$
    – DMGregory
    Sep 9, 2021 at 19:39

1 Answer 1

1
\$\begingroup\$

The method you are looking for is Vector3.RotateTowards(current, target, maxRadiansDelta).

This method allows you to take one direction and move it towards a different direction, but limit the amount of degree by which the rotation can change. And when you multiply that number of degree by Time.deltaTime, then you get exactly what you want: A constant rotation towards the desired direction.

Vector3 current = transform.forward;
Vector3 to = leadObj.position - transform.position;
transform.forward = Vector3.RotateTowards(current, to, turnSpeed * Time.deltaTime)

Where turnSpeed is a float measured in radians per second.

\$\endgroup\$
3
  • \$\begingroup\$ It's working but I need to change the turnSpeed to almost 1000 or even a bit over 1000 for smooth rotation of the head if the turnSpeed is 100 or 500 or 600 the head is stuttering. \$\endgroup\$
    – Daniel Lip
    Sep 9, 2021 at 21:12
  • \$\begingroup\$ I think that if the turnSpeed is for example 100 the head should rotate towards the target but slowly so the target will move fast the head will rotate slower so the head will not follow directly the target but will rotate towards but with delay. The problem is that under 1000 the head is stuttering when rotating towards. \$\endgroup\$
    – Daniel Lip
    Sep 9, 2021 at 21:15
  • \$\begingroup\$ Also the code is inside LateUpdate because the parent have animator and the head child is rotating because the animator so I'm using LateUpdate. \$\endgroup\$
    – Daniel Lip
    Sep 9, 2021 at 21:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .