Search Unity

Make object rotate smoothly toward next waypoint

Discussion in 'Navigation' started by coder_58, Jun 26, 2022.

  1. coder_58

    coder_58

    Joined:
    Mar 29, 2020
    Posts:
    31
    Hi,

    This code controls my player, a plane, that follows a waypoint system (so as to create an autopilot effect):

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. //This allows for the use of lists
    4. using System.Collections.Generic;
    5.  
    6. public class WayPointAutoPilot : MonoBehaviour
    7. {
    8.  
    9.     public List<Transform> wayPointsList = new List<Transform>();
    10.  
    11.     public Transform currentWaypoint;
    12.  
    13.     public int wayPointNumber = 0;
    14.  
    15.     public float speed = 3f;
    16.  
    17.     // Use this for initialization
    18.     void Start()
    19.     {
    20.         currentWaypoint = wayPointsList[wayPointNumber];
    21.     }
    22.  
    23.     // Update is called once per frame
    24.     void Update()
    25.     {
    26.         moveEnemy();
    27.     }
    28.  
    29.     public void moveEnemy()
    30.     {
    31.         float distanceToCurrent = Vector2.Distance(transform.position, currentWaypoint.position);
    32.  
    33.         if (distanceToCurrent == 0)
    34.         {
    35.             if (wayPointNumber != wayPointsList.Count - 1)
    36.             {
    37.                 wayPointNumber++;
    38.                 currentWaypoint = wayPointsList[wayPointNumber];
    39.             }
    40.             else
    41.             {
    42.                 wayPointNumber = 0;
    43.                 currentWaypoint = wayPointsList[wayPointNumber];
    44.             }
    45.         }
    46.  
    47.         transform.position = Vector3.MoveTowards(transform.position, currentWaypoint.position, speed * Time.deltaTime);
    48.         Vector3 relativePos = currentWaypoint.position - transform.position;
    49.         transform.rotation = Quaternion.LookRotation (relativePos);
    50.        
    51.  
    52.     }
    53.  
    54. }
    The problem is that it is rather choppy and turns the player instantaneously when reaching a waypoint. I want this behavior to be smooth and gradual. How would I go about this? Thanks.
     
  2. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    looks like it is because update is called every frame, which does movetowards every frame, you should look into lerp, it sort of distributes movement over the frames and is very smooth. Once you get your head around it that is.

    Or maybe set off a coroutine that does it over time then cancels when complete.
     
  3. Inxentas

    Inxentas

    Joined:
    Jan 15, 2020
    Posts:
    278
    Lerp stands for "linear interpolation". Take into account what you interpolate. If you interpolate the remaining distance over time, the effect will be an easing of sorts as the thing you interpolate becomes smaller over time. If you interpolate the entire distance over time your animation will be linear without any easing.

    Vector3.Lerp(currentPos, destPos, 0.2f) interpolates the remaining distance each frame.
    Vector3.Lerp(startPos, endPos, val) interpolates the entire distance over time.

    In the latter, val should be a value between 0 and 1 indicating how far along the animation you are.
     
    radiantboy likes this.