Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I make that each npc will start moving along the waypoints after 3 seconds of delay?

This is the waypoints manager script attached to empty GameObject :

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

public class WaypointsManager : MonoBehaviour
{
    public GameObject npcPrefab;
    public int numberOfNpcs;
    public GameObject waypointsPrefab;
    public List<GameObject> waypoints = new List<GameObject>();
    public int numberOfWaypoints;
    public bool useWaypointsPrefab = false;

    private GameObject waypointObject;

    // Start is called before the first frame update
    void Awake()
    {
        for (int i = 0; i < numberOfWaypoints; i++)
        {
            if (useWaypointsPrefab)
            {
                waypointObject = Instantiate(npcPrefab, Vector3.zero, Quaternion.identity);
            }
            else
            {
                waypointObject = new GameObject();
            }
            waypointObject.tag = "Waypoint";
            waypointObject.name = "Waypoint";
            waypointObject.transform.position = new Vector3(Random.Range(0, 10), Random.Range(0, 10), Random.Range(0, 10));
            waypoints.Add(waypointObject);
        }

        for (int i = 0; i < numberOfNpcs; i++)
        {
            if (npcPrefab != null)
            {
               GameObject npc = Instantiate(npcPrefab, Vector3.zero, Quaternion.identity);
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

And this script is attached to each npc :

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

public class Waypoints : MonoBehaviour
{
    public List<GameObject> waypoints = new List<GameObject>();
    public float movementSpeed;
    public float rotationSpeed;
    public bool reverse = false;
    public bool go = false;
    public int numberOfWaypoints;
    public int nextWaypointNumber;

    private int waypointIndex = 0;
    private GameObject nextWayPoint;

    // Start is called before the first frame update
    void Start()
    {
        waypoints = GameObject.FindGameObjectsWithTag("Waypoint").ToList();

        numberOfWaypoints = waypoints.Count;

        if (reverse)
        {
            waypointIndex = waypoints.Count - 1;
        }
        else
        {
            waypointIndex = 0;
        }

        StartCoroutine(MoveNpc());
    }

    // Update is called once per frame
    void Update()
    {
        if (go)
        {
            if (reverse && waypointIndex == 0)
            {
                waypointIndex = waypoints.Count - 1;
            }

            if (reverse == false && waypointIndex == waypoints.Count)
            {
                waypointIndex = 0;
            }

            nextWayPoint = waypoints[waypointIndex];
            nextWaypointNumber = waypointIndex;

            transform.position = Vector3.MoveTowards(transform.position,
            waypoints[waypointIndex].transform.position, Time.deltaTime * movementSpeed);

            float distance = Vector3.Distance(transform.position, waypoints[waypointIndex].transform.position);
            if (distance > 0f)
            {
                // Try to rotate to face the waypoint only if we're not on top of it.
                var rotation = Quaternion.LookRotation(nextWayPoint.transform.position - transform.position);
                transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * rotationSpeed);
            }
            else
            {
                numberOfWaypoints--;

                if (reverse)
                {
                    waypointIndex--;
                }
                else
                {
                    waypointIndex++;
                }
            }
        }
    }

    private IEnumerator MoveNpc()
    {
        yield return new WaitForSeconds(3f);

        go = true;
    }

    private void OnDrawGizmos()
    {
        if (waypoints != null)
        {
            for (int i = 0; i < waypoints.Count; i++)
            {
                Gizmos.color = Color.green;
                Gizmos.DrawSphere(waypoints[i].transform.position, 0.1f);
            }
        }

        if (nextWayPoint != null)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawLine(transform.position, nextWayPoint.transform.position);
        }
    }
}

In the Waypoints script I’m starting a coroutine with a 3 seconds delay but still all the npcs are moving at the same time like one npc. I want it to wait 3 seconds send npc wait 3 seconds send npc until all npcs are moving along the waypoints.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

StartCoroutine(MoveNpc());

>Solution :

ISSUE
All npcs are being spawned at the same time, each waits 3 seconds (all at the same time), and then start moving.

SOLUTION
You could create a function that takes the amount of time they need to wait, and use that delay time in your coroutine.

NPC

public void StartMovingAfterSeconds(float seconds) 
{
    StartCoroutine(MoveNPC(seconds));
}
private IEnumerator MoveNpc(float delayTimeSeconds)
{
    yield return new WaitForSeconds(delayTimeSeconds);

    go = true;
}

From your manager you will need to track the delay time as you spawn the npcs.

MANAGER

// Amount to delay movement by (can be exposed in the inspector)
//
var delayTime = 3f;

// Accumulated delay
//
var currentDelay = 0f;

if (npcPrefab != null)
{
    for (int i = 0; i < numberOfNpcs; i++)
    {
        var npc = Instantiate(npcPrefab, Vector3.zero, Quaternion.identity);
       
        npc.StartMovingAfterSeconds(currentDelay);
       
        currentDelay += delayTime;
    }
}

We start with a delay of 0 (currentDelay) and add the amount we want to delay by (delayTime) in each iteration. The first delay is 0, next is 3, then 6, etc..

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading