How to make enemies attack in small groups

Hi. I’m making an action/adventure game.

When the enemies see the player, they all immediately swarm to him. I want them to do this, but I only want small numbers to perform attack moves at once. In many games, like Skyrim and Red Dead Redemption, there’s a manager with several slots for enemies. If one is open, an enemy will fill the slot and attack.

Does anyone know how to do this?

I think I would approach this in two parts, a player script and an enemy script. The player script would have some data structure (a list for argument’s sake) and a function that would add enemies to this list, but only a certain number. It would store any other enemies trying to attack in a queue. It would then tell the first X number of enemies they are allowed to attack the player. When an enemy is defeated they would be removed from the list and the first in the queue would be added in their place. The enemy script would have a bool in their update, say CanAttackPlayer, and a function the player script can call to tell them they can attack the player. If they can attack the player they do that however you want (this depends on your game, what type of enemies etc), if they can’t attack but see the player they may just move around the area looking threatening or whatever you want.

Player Script:

using System.Collections.Generic;
using UnityEngine;

public class AttackingEnemies : MonoBehaviour
{
    List<EnemyController> attackingEnemies = new List<EnemyController>();
    Queue<EnemyController> attackingEnemiesQueue = new Queue<EnemyController>();
    public int maxAttackingEnemies;

    public void AddAttackingEnemy(EnemyController enemy)
    {
        if (attackingEnemies.Count > maxAttackingEnemies)
        {
            attackingEnemiesQueue.Enqueue(enemy);
        }
        else
        {
            attackingEnemies.Add(enemy);
            enemy.SetCanAttackPlayer(true);
        }
    }

    public void EnemyDied(EnemyController enemy)
    {
        if(enemy.GetCanSeePlayer())
        {
            if(enemy.GetCanAttackPlayer())
            {
                attackingEnemies.Remove(enemy);
                if(attackingEnemiesQueue.Count > 0)
                {
                    attackingEnemies.Add(attackingEnemiesQueue.Dequeue());
                }
            }
        }
    }
}


Enemy Script:

using UnityEngine;

public class EnemyController : MonoBehaviour
{
    bool canAttackPlayer = false;
    public int health = 1;
    public AttackingEnemies playerScript;
    bool canSeePlayer = true;

    //Your detection stuff would call this
    void SeenPlayer()
    {
        canSeePlayer = true;
        playerScript.AddAttackingEnemy(this);
    }

    // Update is called once per frame
    void Update()
    {
        if(canAttackPlayer)
        {
            //attack player
        }
        else
        {
            //Look threatening
        }

        if(health <= 0)
        {
            Die();
        }
    }

    public void SetCanAttackPlayer(bool value)
    {
        canAttackPlayer = value;
    }

    public bool GetCanAttackPlayer()
    {
        return canAttackPlayer;
    }

    void Die()
    {
        playerScript.EnemyDied(this);
        Destroy(gameObject);
    }

    public bool GetCanSeePlayer()
    {
        return canSeePlayer;
    }

}



I’ve not tested these scripts but hopefully will give you a base to jump off of and play around with in your own project.