0
\$\begingroup\$

The same script is attached to some multiple agents. On one of them the flag waitToMove is set to true. And it does getting to the line :

StartCoroutine(WaitToMove(10));

But still all the agents including the one with the flag set to true start moving when starting the game.

How can I make that agents with the script that the flag waitToMove is set to true will wait X seconds one agent will wait 5 seconds other will wait 3 seconds and this one will wait 10 seconds ?

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

public class AgentControl : MonoBehaviour
{
    public List<Transform> points;
    public bool waitToMove = false;

    private int destPoint = 0;
    private NavMeshAgent agent;
    private Transform originalPos;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();

        // Disabling auto-braking allows for continuous movement
        // between points (ie, the agent doesn't slow down as it
        // approaches a destination point).
        agent.autoBraking = false;

        originalPos = transform;
        points.Add(originalPos);

        if (waitToMove == false)
        {
            GotoNextPoint();
        }
        else
        {
            StartCoroutine(WaitToMove(10));
        }
    }


    void GotoNextPoint()
    {
        // Returns if no points have been set up
        if (points.Count == 0)
            return;

        // Set the agent to go to the currently selected destination.
        agent.destination = points[destPoint].position;

        // Choose the next point in the array as the destination,
        // cycling to the start if necessary.
        destPoint = (destPoint + 1) % points.Count;
    }


    void Update()
    {
        // Choose the next destination point when the agent gets
        // close to the current one.
        if (!agent.pathPending && agent.remainingDistance < 1f)
            GotoNextPoint();
    }

    IEnumerator WaitToMove(int WaitTime)
    {
        yield return new WaitForSeconds(WaitTime);
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Your WaitToMove function does nothing at all after waiting, it just ends. None of the rest of your script - which continues running while WaitToMove is waiting - ever checks whether WaitToMove is still waiting, so it's unclear to me how you expected this code to accomplish anything at all. \$\endgroup\$
    – DMGregory
    May 13 '20 at 19:24
0
\$\begingroup\$

Can you do something like this instead?

   //two vars for handling timer
   float timer = 0;
   //notice WaitTime is a float now
   float WaitTime = 10f;       
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();

        // Disabling auto-braking allows for continuous movement
        // between points (ie, the agent doesn't slow down as it
        // approaches a destination point).
        agent.autoBraking = false;

        originalPos = transform;
        points.Add(originalPos);

    }

void Update()
{
    // Choose the next destination point when the agent gets
    // close to the current one.
    if (!agent.pathPending && agent.remainingDistance < 1f)
    {
        //if wait to move is true
        if (waitToMove)
        {
            //if timer is less than 10
            if (timer < WaitTime)
            {
                //add Time.deltaTime each time we hit this point
                timer += Time.deltaTime;
            }
            //no longer waiting because timer is greater than 10
            else
            { 

                waitTomove = false;
            }
        } 
        //if we hit here waitToMove is false, so go ahead as usual
        else
        {
            GotoNextPoint();
        }
    }

}

If you want to make the agent wait again after the first time, you will need to set the timer equal to 0 again and set WaitToMove to true, but you can ofcourse add a small function that handles this, infact I'd recommend it.

If you are wanting to randomize the waitTime you can do something like this

//define min and max WaitTime
float waitMinTime = 1f;
float waitMaxTime = 10f;
void Start()
{
    agent = GetComponent<NavMeshAgent>();

    // Disabling auto-braking allows for continuous movement
    // between points (ie, the agent doesn't slow down as it
    // approaches a destination point).
    agent.autoBraking = false;
    //set WaitTime to equal a random number between min and max
    WaitTime = Random.Range(waitMinTime, waitMaxTime);
    originalPos = transform;
    points.Add(originalPos);

}

So you mentioned in the comments that you also want to add the Objects original position to the end of the list, so when it is finished it will return the its starting position, a patrol.

But you are not doing this you are adding the objects transform reference to the list, this transform is attached to the object so it will be wherever the object is, leading to mini stuttering as it arrives at the original position AND starts moving to it in between frames.

You can test this to see what I mean, leave your code as it is, take one of the transforms 'points' in your level and move it, the agent moves to where the point currently is right? Now Imagine that 'point' is attached to the Agent itself, you might be able to see why its stuttering!

You need to take a snap shot of the position once, and add that I would do it something like this.

Also because you are adding a list of transforms and not a list of positions (Vector3) we will need to create a new GameObject (with transform, they both exist together)

void Start()
{
    agent = GetComponent<NavMeshAgent>();

    // Disabling auto-braking allows for continuous movement
    // between points (ie, the agent doesn't slow down as it
    // approaches a destination point).
    agent.autoBraking = false;
    //set WaitTime to equal a random number between min and max
    WaitTime = Random.Range(waitMinTime, waitMaxTime);

    //transforms dont exist without A GameObject and a GameObject doesn't exist without a transform
    //create a new GameObject to hold our position
    GameObject originalPositionObject = new GameObject();
    //set the new gameobjects position equal to where the transform is right now
    originalPositionObject.transform.position = transform.position;
    //add this to the points list instead
    points.Add(originalPositionObject.transform);

}

I hope I've understood you correctly!

\$\endgroup\$
9
  • \$\begingroup\$ Still both agents start moving at the start because in the Update this two lines : if (!agent.pathPending && agent.remainingDistance < 1f) GotoNextPoint(); and if I will remove this two lines the first agent will move to the first waypoint on start the second will wait 10 seconds then will move to his first waypoint but they will never continue to the other waypoints and I also want them to make loop. \$\endgroup\$ May 13 '20 at 20:00
  • \$\begingroup\$ Updated my answer, I have to edit a few times because the formatting went to garbage, should be correct now. \$\endgroup\$ May 13 '20 at 20:09
  • \$\begingroup\$ Working great. and about this two lines in the Start originalPos = transform; points.Add(originalPos); I want that the agents will also include in the waypoints the original start position of them but this two lines not really move them to the original start position. The second agent that waited 10 second keep staying on the first waypoint and a bit stuttering and not moving to the original start position(last waypoint). \$\endgroup\$ May 13 '20 at 20:27
  • \$\begingroup\$ Can you edit a list of the waypoints into the original answer so I can see what you are working with, I think this is happening because you are not setting a point in start, you are adding the transform reference for that object, so you are really telling it to move to itself. I will update answer as there is more room to explain. \$\endgroup\$ May 13 '20 at 20:34
  • \$\begingroup\$ You right about telling the agent to go it self I just not sure ho to add the original start position. The waypoints I added in the Inspector for each agent only the start position I did in the script. (Saw your edited answer and will try it now). \$\endgroup\$ May 13 '20 at 20:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .