Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Multiple instance of AI script only move one Game Object.

Discussion in 'Navigation' started by gLeevey, Sep 6, 2021.

  1. gLeevey

    gLeevey

    Joined:
    May 28, 2020
    Posts:
    5
    I have this problem when I have two Game Objects with the same Enemy script. They both call the Move function but only one object moves accordingly.

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.AI;
    4.  
    5. [System.Serializable]
    6. public class MainEnemy : MonoBehaviour
    7. {
    8.     #region Variables
    9.     [System.NonSerialized] static NavMeshAgent enemyBrain;
    10.  
    11.     [System.NonSerialized] [SerializeField] GameObject player;
    12.  
    13.  
    14.     [System.NonSerialized] static Transform enemyObject;
    15.  
    16.     [SerializeField] float viewDistance = 5f;
    17.     [SerializeField] int id;
    18.  
    19.     static float alertSpeed = 9f;
    20.     static float idleSpeed = 5f;
    21.     float waitMove;
    22.     float waitCheck;
    23.  
    24.     static float AlertRadius = 30f;
    25.     static float DeathRadius = 4f;
    26.     static float DifficultyMult = 1f;
    27.  
    28.     static State enemyState;
    29.  
    30.     bool moving;
    31.     bool waiting;
    32.  
    33.     // Save location when saving.
    34.     [System.NonSerialized] static Vector3 TargetLocation;
    35.     float targetX;
    36.     float targetY;
    37.     float targetZ;
    38.  
    39.     #endregion
    40.  
    41.     public void Start()
    42.     {
    43.         enemyBrain = GetComponent<NavMeshAgent>();
    44.         enemyObject = transform;
    45.         player = GameObject.Find("Player");
    46.         enemyState = State.IDLE;
    47.     }
    48.  
    49.     public void Update()
    50.     {
    51.         if (enemyState == State.IDLE)
    52.         {
    53.             enemyBrain.speed = idleSpeed;
    54.             Move();
    55.         }
    56.         else if (enemyState != State.IDLE)
    57.         {
    58.             CheckPlayer();
    59.         }
    60.     }
    61.  
    62.     // Alert enemy of a sound
    63.     public void AlertEnemy(Vector3 soundLocation, float soundLevel /*sound volume*/ )
    64.     {
    65.         // if enemy is chasing the player ignore sound alerts
    66.         if (enemyState == State.CHASE)
    67.             return;
    68.  
    69.         // detect sound location and if it is close enough to the enemy
    70.         if (Vector3.Distance(enemyObject.position, soundLocation) <= AlertRadius * DifficultyMult * (soundLevel - 0.2f))
    71.         {
    72.             enemyState = State.ALERT;
    73.             enemyBrain.speed = alertSpeed;
    74.             enemyBrain.SetDestination(soundLocation);
    75.         }
    76.     }
    77.  
    78.     // Check if the enemy can see the player and is alerted
    79.     void CheckPlayer()
    80.     {
    81.         RaycastHit hit;
    82.         if (Physics.Raycast(transform.position, player.transform.position - transform.position, out hit, viewDistance * DifficultyMult))
    83.         {
    84.             if (hit.transform.name != "Player")
    85.             {
    86.                 return;
    87.             }
    88.  
    89.             enemyState = State.CHASE;
    90.             enemyBrain.SetDestination(player.transform.position);
    91.             Debug.Log("Chasing Player");
    92.         }
    93.  
    94.         if (Physics.Raycast(transform.position, player.transform.position - transform.position, out hit, viewDistance * DifficultyMult))
    95.         {
    96.             if(hit.transform.name != "Player")
    97.             {
    98.                 enemyState = State.IDLE;
    99.                 return;
    100.             }
    101.  
    102.             if(Vector3.Distance(hit.transform.position, transform.position) > viewDistance * DifficultyMult)
    103.             {
    104.                 enemyState = State.IDLE;
    105.             }
    106.         }
    107.  
    108.         if (Vector3.Distance(enemyObject.position, player.transform.position) <= DeathRadius)
    109.         {
    110. #if UnityEditor
    111.             UnityEditor.EditorApplication.isPlaying = false;
    112. #endif
    113.         }
    114.     }
    115.  
    116.     private void Move() // Random Move
    117.     {
    118.         Vector2 position = new Vector2(transform.position.x, transform.position.z);
    119.         Vector2 targetPosition = new Vector2(TargetLocation.x, TargetLocation.z);
    120.  
    121.         if(moving)
    122.         {
    123.             // Check if cannot reach destination.
    124.             if (Time.time >= waitCheck + 3f + (Vector2.Distance(position, targetPosition) / enemyBrain.speed) && !waiting)
    125.             {
    126.                 StartCoroutine("Wait");
    127.                 moving = false;
    128.                 enemyBrain.SetDestination(transform.position);
    129.             }
    130.  
    131.             //Check if destination has been reached.
    132.             if (Vector2.Distance(position, targetPosition) <= 1f && !waiting)
    133.             {
    134.                 StartCoroutine("Wait");
    135.                 moving = false;
    136.             }
    137.             else
    138.             {
    139.                 return;
    140.             }
    141.         }
    142.  
    143.         if (waiting)
    144.         {
    145.             return;
    146.         }
    147.        
    148.         // Get the bounds for random movement
    149.         GameObject[] bounds = GameObject.FindGameObjectsWithTag("EnemyBounds");
    150.  
    151.         enemyBrain.SetDestination(TargetLocation);
    152.  
    153.         // generate random number
    154.         int r = UnityEngine.Random.Range(0, bounds.Length);
    155.  
    156.         TargetLocation = RandomPointInBounds(bounds[r].GetComponent<Collider>().bounds);
    157.  
    158.         waitCheck = Time.time;
    159.  
    160.         moving = true;
    161.     }
    162.  
    163.     IEnumerator Wait()
    164.     {
    165.         float r = UnityEngine.Random.Range(7, 25) / 10;
    166.         waiting = true;
    167.         yield return new WaitForSeconds(1f);
    168.         waiting = false;
    169.         moving = false;
    170.     }
    171.  
    172.     public Vector3 RandomPointInBounds(Bounds bounds)
    173.     {
    174.         return new Vector3(
    175.             UnityEngine.Random.Range(bounds.min.x, bounds.max.x),
    176.             (bounds.min.y + bounds.max.y) / 2,
    177.             UnityEngine.Random.Range(bounds.min.z, bounds.max.z)
    178.         );
    179.     }
    180.  
    181. }
     
  2. ChrisKurhan

    ChrisKurhan

    Joined:
    Dec 28, 2015
    Posts:
    268
    You have the NavMeshAgent and a GameObject defined as "static" so there is only 1 of them. If you remove the "static" keyword I think that will make it so your script works as you would like it to.
     
  3. gLeevey

    gLeevey

    Joined:
    May 28, 2020
    Posts:
    5
    Thanks that worked. I originally had a static method, that is why they were static.
     
    ChrisKurhan likes this.