How can I make my droid to move between waypoints ?

The droid is in at static height at the start not on the floor/surface but floating a bit in the air.
The droid also have animator but don’t have for now any rigidbody.

What I want to do is that the droid will visit waypoints will move smooth between the waypoints when getting to the next waypoint smoothly rotate facing the next waypoint don’t stop and rotate but while in the current waypoint rotate and keep moving to the next waypoint.

  • How should I make the waypoint script ?

  • Should I use navmesh agent too on the droid ? I don’t want the droid to hit other characters.

  • I want that the droid will move in a loop but randomly between the waypoints(The random part is an option) and sometimes randomly I want that if the droid is distance from specific objects tagged “Humans” for example distance 5 then sometimes randomly move out the waypoints structure and face the “Humans”(specific closet human).

Problems :

  • With this script now the droid stutter when moving to the first waypoint. If I remove/disable the animator the droid will move smooth but I want it to move smooth with the animator enabled.

I need the animator, The animator make the droid idle shoot and more animations while floating in the air so it’s important to keep the animator enabled when moving the droid between the waypoints.

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

public class Waypoints : MonoBehaviour
{
   public Transform[] waypoints;
   public float waypointRadius = 1.5f;
   public float damping = 0.1f;
   public bool loop = false;
   public float speed = 2.0f;
   public bool faceHeading = true;
   public GameObject objectToPatrol;

   private Vector3 currentHeading, targetHeading;
   private int targetwaypoint;
   private Transform xform;
   private bool useRigidbody;
   private Rigidbody rigidmember;


   // Use this for initialization
   protected void Start()
   {
       if (objectToPatrol == null)
       {
           xform = transform;
       }
       else
       {
           xform = objectToPatrol.transform;
       }

       currentHeading = xform.forward;
       if (waypoints.Length <= 0)
       {
           Debug.Log("No waypoints on " + name);
           enabled = false;
       }
       targetwaypoint = 0;
       if (GetComponent<Rigidbody>() != null)
       {
           useRigidbody = true;
           rigidmember = GetComponent<Rigidbody>();
       }
       else
       {
           useRigidbody = false;
       }
   }


   // calculates a new heading
   protected void FixedUpdate()
   {
       targetHeading = waypoints[targetwaypoint].position - xform.position;

       currentHeading = Vector3.Lerp(currentHeading, targetHeading, damping * Time.deltaTime);
   }

   // moves us along current heading
   protected void Update()
   {
       if (useRigidbody)
           rigidmember.velocity = currentHeading * speed;
       else
           xform.position += currentHeading * Time.deltaTime * speed;
       if (faceHeading)
           xform.LookAt(xform.position + currentHeading);

       if (Vector3.Distance(xform.position, waypoints[targetwaypoint].position) <= waypointRadius)
       {
           targetwaypoint++;
           if (targetwaypoint >= waypoints.Length)
           {
               targetwaypoint = 0;
               if (!loop)
                   enabled = false;
           }
       }
   }


   // draws red line from waypoint to waypoint
   public void OnDrawGizmos()
   {
       Gizmos.color = Color.red;
       if (waypoints == null)
           return;
       for (int i = 0; i < waypoints.Length; i++)
       {
           Vector3 pos = waypoints[i].position;
           if (i > 0)
           {
               Vector3 prev = waypoints[i - 1].position;
               Gizmos.DrawLine(prev, pos);
           }
       }
   }
}

Do not use Time.deltaTime within FixedUpdate(). FixedUpdate() is tied to the physics refresh rate, which does not match the framerate of the game. Therefore Time.deltaTime is not an accurate indicator of the amount of time that has passed since the previous FixedUpdate() call. In FixedUpdate() it would be more appropriate to use Time.fixedDeltaTime.

1 Like