Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Zombie Horde Movement

Discussion in 'Navigation' started by laspencer, May 20, 2017.

  1. laspencer

    laspencer

    Joined:
    Jul 7, 2013
    Posts:
    4
    Hello,

    I am working on a Top-Down (for now) survival shooter. I am am experienced programmer (fairly new to Unity). I have used Unity's navmesh and understand how it works. I am wondering how I would do horde AI. Not only following the player, but some choosing to attack and attempt to break down windows / doors, and others taking the easiest path through already open doors.

    Basically, how do I limit a window to maybe 5 or 6 zombies at a time trying to get through while the rest choose a different entrance? How is something like this usually done in Unity with the navmesh system. I am not asking for someone to code it for me, just the best approach. Thank you
     
  2. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    Id be curious how others may work on this.

    Some ideas- use multiple targets.
    have a simple list script for attackable objects.
    When an object is attacked by a zombie add that zombie to its list.
    only let a zombie attack an object that has an open list of attackers.
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class JBR_AI_Search_System : MonoBehaviour {
    7. //add proper tags in inspector
    8. public string playerTag;
    9. public string npcTag;
    10. public string MiscTargetTag;
    11.  
    12. // allow targeting of each type of target
    13. public bool canTargetPlayerTag;
    14. public bool canTargetNPCTag;
    15. public bool canTargetMiscTargetTag;
    16.  
    17.  //list of all targets
    18.     public List<GameObject> allTargets = new List<GameObject>();
    19.     //array of each target type
    20.     public GameObject[] playerTargets;
    21.     public GameObject[] NPCTargets;
    22.     public GameObject[] miscTargets;
    23.  
    24.  // Use this for initialization
    25.     void Start()
    26.     {
    27. //optimization does this check 10 times per second vs. 30-60 times in regular update
    28.  InvokeRepeating("CheckForTargets", 0.1f, 0.1f);
    29. }
    30. void CheckForTargets(){
    31.  //clear list of targets before we redo the list
    32.             allTargets.Clear();
    33.             //if checked add all player targets
    34.             if (canTargetPlayerTag)
    35.             {
    36.                 playerTargets = GameObject.FindGameObjectsWithTag(playerTag);
    37.                 for (int i = 0; i < playerTargets.Length ; i++)
    38.                 {
    39.                     allTargets.Add(playerTargets[i]);
    40.                     Debug.Log(playerTargets[i]);
    41.                 }
    42.             }
    43.             //if checked add all NPC targets
    44.             if (canTargetNPCTag)
    45.             {
    46.                 NPCTargets = GameObject.FindGameObjectsWithTag(npcTag);
    47.                 for (int i = 0; i < NPCTargets.Length ; i++)
    48.                 {
    49.                     allTargets.Add(NPCTargets[i]);
    50.                 }
    51.             }
    52.             //if checked add all Misc targets
    53.             if (canTargetMiscTargetTag)
    54.             {
    55.                 miscTargets = GameObject.FindGameObjectsWithTag(MiscTargetTag);
    56.                 for (int i = 0; i < miscTargets.Length ; i++)
    57.                 {
    58.                     allTargets.Add(miscTargets[i]);
    59.                 }
    60.             }
    61.             //checked through list of all targets
    62.             if (allTargets.Count > 0)
    63.             {
    64.                 for (int i = 0; i < allTargets.Count ; i++)
    65.                 {
    66.              
    67.                     //sift through all the targets for the best one
    68.                     // checks the distance away from ai to target
    69.                     float cDistance = Vector3.Distance(this.transform.position, allTargets[i].transform.position);
    70. Debug.Log("All Targets - " + allTargets[i] + "distance " + cDistance);
    71. }
    72.  
     
    Last edited: May 22, 2017
    philippecaseiro and Bojangl like this.
  3. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    708
    Attackers handling
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. // basic Aggro handling of anything that can be attacked
    6. public class JBR_AttackableObject : MonoBehaviour {
    7.  
    8.     public int maxAttackers = 6;        //max allowed attackers
    9.     public GameObject[] Attackers ;     //Array of attackers
    10.     public bool LimitReached = false;   //if array is full sets to true
    11.  
    12.  
    13. // Use this for initialization
    14.     void Start () {
    15.         Attackers = new GameObject[maxAttackers];
    16.         Debug.Log(Attackers.Length);
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update () {
    21.  
    22.     }
    23.     //method for adding Attackers
    24.     public void TakeDamage(GameObject attackerGO)
    25.     {
    26.         //look through all array slots
    27.         for (int i = 0; i < Attackers.Length +1; i++)
    28.         {
    29.             // first we check that this attacker hasnt been added to the array already
    30.             if(Attackers[i] == attackerGO)
    31.             {
    32.                 Debug.Log("Duplicate Attacker " + this.gameObject.name);
    33.                 return;
    34.             }
    35.             //next we add the attacker to the first open slot in the array
    36.             if(Attackers[i] == null )
    37.             {
    38.              
    39.                 Attackers[i] = attackerGO;
    40.                 Debug.Log("New Attacker added " + this.gameObject.name);
    41.                 return;
    42.             }
    43.             //if we made it to maxAttackers limit then set as limit reached
    44.             if(i >= maxAttackers)
    45.             {
    46.                 LimitReached = true;
    47.                 Debug.Log("Limit Reached " + this.gameObject.name);
    48.                 return;
    49.             }
    50.         }
    51.     }
    52.     //method for removing Attackers
    53.     public void RemoveAttacker(GameObject removedAttacker)
    54.     {
    55.         //look through all array slots
    56.         for (int i = 0; i < Attackers.Length; i++)
    57.         {
    58.             if (Attackers[i] == removedAttacker)
    59.             {
    60.                 LimitReached = false;
    61.                 Attackers[i] = null;
    62.                 Debug.Log("Removed Attacker " + this.gameObject.name);
    63.                 return;
    64.             }
    65.         }
    66.     }
    67. }
     
    Bojangl likes this.