Multiple enemies on random paths?


#1

Hello everyone! I’ve used A* for a 2D top-down game I’m creating. So far, I’ve managed to write up some code that will allow my enemy to choose a random object node and travel there. Everything works fine but I’m having an issue trying to do the same but with multiple enemy objects. Even though I’ve duplicated the enemy object (script and all components as well) when I run my game only the main enemy object moves and the others stay idle.

How can I implement this but NOT in a group-patrol manor? Each enemy MUST be able to choose their own random paths.

public class AstarAI : MonoBehaviour
{

        public Transform [] PatrolPoints;

        int PatrolPointsIndex;       

        //The point to move to
        Transform target;
       
        private Seeker seeker;

        //The calculated path
        public Path path;        

        //The AI's speed per second
        public float speed = 2;

        //The max distance from the AI to a waypoint for it to continue to the next waypoint
        public float nextWaypointDistance = 2;

        //The waypoint we are currently moving towards
        private int currentWaypoint = 0;



  public void Start ()
  {

        

  }

    public void Update()
    {     

        if (Global_Variables.EnemyPatrol == true)
        {
            _EnemyPatrol();          
        }

        if(Global_Variables.EnemyFollow == true)
        {
            _EnemyFollow(); 
        }
       

    }

    public void _EnemyPatrol()
    {

        Global_Variables.EnemyPatrol = false;

        seeker = GetComponent<Seeker>();
        PatrolPointsIndex = Random.Range(0, PatrolPoints.Length);
        target = PatrolPoints[PatrolPointsIndex];

        //Start a new path to the targetPosition, return the result to the OnPathComplete function
        seeker.StartPath(transform.position, target.position, OnPathComplete);

    }

    public void _EnemyFollow()
    {

        target = GameObject.Find("Player").GetComponent<Transform>();

        

    }

    public void OnPathComplete ( Path p )
  {

    Debug.Log( "Yay, we got a path back. Did it have an error? " + p.error );
    if (!p.error)
    {
      path = p;
      //Reset the waypoint counter
      currentWaypoint = 0;

     }

  }

  public void FixedUpdate ()
  {
    if (path == null)
    {
      //We have no path to move after yet
      return;
    }

    if (currentWaypoint >= path.vectorPath.Count)
    {
      
      Debug.Log( "End Of Path Reached" );

      Global_Variables.EnemyPatrol = true;

      return;

    }

    //Direction to the next waypoint
    Vector3 dir = ( path.vectorPath[ currentWaypoint ] - transform.position ).normalized;
    dir *= speed * Time.fixedDeltaTime;
    this.gameObject.transform.Translate( dir );

    //Check if we are close enough to the next waypoint
    //If we are, proceed to follow the next waypoint
    if (Vector3.Distance( transform.position, path.vectorPath[ currentWaypoint ] ) < nextWaypointDistance)
    {
      currentWaypoint++;
      return;
    }
  }
}

Thank you in advance!


#2

Hi

Well, those global variables look suspicious. Maybe you want to try to move them to local variables instead?

Also. You are requesting a new path every frame without waiting for the previous path to complete, that is really bad. Path calculations are asynchronous, so they may take one or more frames to calculate, if you repeatedly request new paths they will cancel the previous path requests. Check if seeker is currently calculating a path using seeker.IsDone.