Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Simulation Coroutines to run the enemies at my hideout

Discussion in 'Projects In Progress' started by Kurt-Dekker, Sep 14, 2021.

  1. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    37,162
    This post is especially dedicated to GroZZleR, who posted in another forum:

    Look @GroZZleR! I'm using coroutines to run my enemy hideout agents, a new level and game mode coming soon to my ATGM game!

    Here's the code, just so you can see I'm not COMPLETELY allergic to coroutines.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5.  
    6. // runs ALL the enemies at this hideout
    7.  
    8. public class HideoutBehaviours : MonoBehaviour
    9. {
    10.     public NavMeshAgent EnemyPrefab;
    11.  
    12.     // simulator-level "I am alarmed" status:
    13.     // tripped when there is an explosion or dead body, for example
    14.     public bool alarmed;
    15.  
    16.     [Header( "Parent object of all spawns / patrol points")]
    17.     public GameObject Spawns;
    18.     public GameObject Patrols;
    19.  
    20.     Transform FindRandomSpawn()
    21.     {
    22.         int n = Random.Range( 0, Spawns.transform.childCount);
    23.  
    24.         var tr = Spawns.transform.GetChild( n);
    25.  
    26.         return tr;
    27.     }
    28.  
    29.     Transform FindRandomPatrol()
    30.     {
    31.         int n = Random.Range( 0, Patrols.transform.childCount);
    32.  
    33.         var tr = Patrols.transform.GetChild( n);
    34.  
    35.         return tr;
    36.     }
    37.  
    38.     void Start ()
    39.     {
    40.         StartCoroutine( RunEnemies());
    41.     }
    42.  
    43.     // marker used in GenericMarker tag script
    44.     const string s_OurEnemies = "ztestonly_enemy_hideout_1_enemies";
    45.  
    46.     IEnumerator RunEnemies()
    47.     {
    48.         if (EnemyPrefab.gameObject.activeInHierarchy)
    49.         {
    50.             EnemyPrefab.gameObject.SetActive(false);
    51.         }
    52.  
    53.         while( true)
    54.         {
    55.             yield return new WaitForSeconds( Random.Range( 1.0f, 3.0f));
    56.  
    57.             if (alarmed)
    58.             {
    59.                 // extra wait between alarm checks
    60.                 yield return new WaitForSeconds( Random.Range( 2.0f, 4.0f));
    61.  
    62.                 // do nothing, everybody is skedaddling
    63.                 var markers = FindObjectsOfType<GenericMarker>();
    64.                 bool RemainAlarmed = false;
    65.  
    66.                 foreach( var marker in markers)
    67.                 {
    68.                     if (marker.Identity == s_OurEnemies)
    69.                     {
    70.                         RemainAlarmed = true;
    71.                     }
    72.                 }
    73.  
    74.                 // once everbody didis outa here and some time passes, chill
    75.                 if (!RemainAlarmed)
    76.                 {
    77.                     yield return new WaitForSeconds( Random.Range( 2.0f, 4.0f));
    78.                     alarmed = false;
    79.                 }
    80.             }
    81.             else
    82.             {
    83.                 var dude = Instantiate<NavMeshAgent>( EnemyPrefab);
    84.                 dude.transform.position = FindRandomSpawn().position;
    85.                 dude.gameObject.SetActive( true);
    86.  
    87.                 dude.gameObject.AddComponent<GenericMarker>().Identity = s_OurEnemies;
    88.  
    89.                 StartCoroutine( RunMeJohnny( dude));
    90.             }
    91.         }
    92.     }
    93.  
    94.     IEnumerator UpdateSpeed( NavMeshAgent agent)
    95.     {
    96.         float NormalSpeed = Random.Range( 2.0f, 4.0f);
    97.  
    98.         float AlarmedSpeed = Random.Range( 10.0f, 14.0f);
    99.  
    100.         while(true)
    101.         {
    102.             if (alarmed)
    103.             {
    104.                 agent.speed = AlarmedSpeed;
    105.             }
    106.             else
    107.             {
    108.                 agent.speed = NormalSpeed;
    109.             }
    110.  
    111.             // not everybody instantly alarms!
    112.             yield return Random.Range( 0.5f, 1.0f);
    113.  
    114.             if (!agent) yield break;
    115.         }
    116.     }
    117.  
    118.     IEnumerator RunMeJohnny( NavMeshAgent agent)
    119.     {
    120.         float lifeTime = Random.Range( 20.0f, 50.0f);
    121.         bool departing = false;
    122.  
    123.         StartCoroutine( UpdateSpeed( agent));
    124.  
    125.         while( true)
    126.         {
    127.             // is it reason for me to go away?
    128.             if (alarmed)
    129.             {
    130.                 departing = true;
    131.             }
    132.  
    133.             // is it time for me to go away?
    134.             if (lifeTime < 0)
    135.             {
    136.                 departing = true;
    137.             }
    138.  
    139.             Vector3 destination = FindRandomPatrol().position;
    140.  
    141.             if (departing)
    142.             {
    143.                 destination = FindRandomSpawn().position;
    144.             }
    145.  
    146.             agent.SetDestination( destination);
    147.  
    148.             while( true)
    149.             {
    150.                 lifeTime -= Time.deltaTime;
    151.  
    152.                 if (Vector3.Distance( agent.transform.position, destination) < 1)
    153.                 {
    154.                     break;
    155.                 }
    156.  
    157.                 yield return null;
    158.  
    159.                 if (!agent) yield break;
    160.  
    161.                 // alarm has happened, abandon our patrol
    162.                 if (alarmed && !departing)
    163.                 {
    164.                     break;
    165.                 }
    166.             }
    167.  
    168.             if (departing)
    169.             {
    170.                 Destroy(agent.gameObject);
    171.                 yield break;
    172.             }
    173.  
    174.             yield return null;
    175.  
    176.             if (!agent) yield break;
    177.         }
    178.     }
    179. }
    180.  
     
    GroZZleR likes this.
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    I imagine this is what a proud papa seeing his child walk for the first time feels like.
     
    Kurt-Dekker likes this.