简体   繁体   English

我怎样才能让每个 npc 在延迟 3 秒后开始沿着航路点移动?

[英]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:这个脚本附在每个 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.在 Waypoints 脚本中,我正在启动一个延迟 3 秒的协程,但所有 npc 仍然像一个 npc 一样同时移动。 I want it to wait 3 seconds send npc wait 3 seconds send npc until all npcs are moving along the waypoints.我希望它等待 3 秒发送 npc 等待 3 秒发送 npc 直到所有 npc 沿着航路点移动。

StartCoroutine(MoveNpc());

ISSUE问题
All npcs are being spawned at the same time, each waits 3 seconds (all at the same time), and then start moving.所有 NPC 同时生成,每个等待 3 秒(全部同时),然后开始移动。

SOLUTION解决方案
You could create a function that takes the amount of time they need to wait, and use that delay time in your coroutine.您可以创建一个 function 来花费他们需要等待的时间,并在您的协程中使用该延迟时间。

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.从您的经理那里,您需要在生成 npc 时跟踪延迟时间。

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.我们从延迟 0 (currentDelay) 开始,并在每次迭代中添加我们想要延迟的量 (delayTime)。 The first delay is 0, next is 3, then 6, etc..第一个延迟是 0,接下来是 3,然后是 6,依此类推。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM