Menu
CoddyTech

Turn Smoothly

Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 45 of 71.

Setting transform.rotation straight to a new rotation turns an object in a single frame. Quaternion.RotateTowards(current, goal, maxDegrees) returns current turned toward goal by at most maxDegrees, and never past the goal. With turnSpeed * Time.deltaTime as the step, the object turns at a steady rate and stops exactly on its goal, as MoveTowards does for positions. This sunflower follows the sun at 30 degrees per second:

public Transform sun;
public float turnSpeed = 30f;

void Update()
{
    Quaternion goal = Quaternion.LookRotation(sun.position - transform.position);
    transform.rotation = Quaternion.RotateTowards(transform.rotation, goal, turnSpeed * Time.deltaTime);
}

A sun 90 degrees away takes the sunflower 3 seconds, 30 degrees in each. It turns the short way round, and the goal is worked out again on every frame, so a moving sun is followed.

Quaternion.Slerp(a, b, t) is the rotation a fraction t of the way from a to b, as Vector3.Lerp is for points. Written as Slerp(transform.rotation, goal, 5f * Time.deltaTime) in Update(), it turns a share of the remaining angle on each frame: quick at first, slower and slower near the goal, never at a set speed and never quite arriving. That ease suits a camera or a head turning. When the turn rate is a rule of the game, such as a cannon that turns 60 degrees a second, use RotateTowards.

challenge icon

Challenge

Medium

Make the owl turn smoothly to the way each arrow points.

  1. Add Quaternion goal; and set it to transform.rotation in Start().
  2. On Input.GetKeyDown of each arrow, set goal, for example goal = Quaternion.LookRotation(Vector3.right);: up +z, right +x, down -z, left -x.
  3. Every frame, set transform.rotation = Quaternion.RotateTowards(transform.rotation, goal, turnSpeed * Time.deltaTime);.

Press Play and tap the arrows. Then Check.

Try it yourself

using UnityEngine;

public class Owl : MonoBehaviour
{
    public float turnSpeed = 180f;

    void Update()
    {
        // Up, right, down, left: turn to face +z, +x, -z, -x at turnSpeed degrees per second.
    }
}

All lessons in Physics and Gameplay

Practice on your own: Unity playground