I want to make a Monster Spawner that spawns a monster in every x seconds (in real time); but I can't get timer to work properly...

I’m trying to make a Spawner, which will Instantiate a prefab in every x seconds. I tried many times, but I can’t get coroutines to work properly. This is the last form of code; which waits x seconds before spawning any prefab; after that, summons all monsters immediately. I don’t know what am I missing; any help will be welcomed!
TY for taking time!


using System.Collections;
using UnityEngine;

public class MonsterSpawner : MonoBehaviour
{
    public GameObject[] spawnPoints;
    
    public int monstersCount;

    public GameObject monster2;
    private GameObject monsterSprite;

    public float spawnDelay = 5f;

    void FixedUpdate()
    {
        if (monstersCount < 1)
            Destroy(gameObject);

        StartCoroutine(SpawnMonster());
    }

    IEnumerator SpawnMonster()
    {
        yield return new WaitForSecondsRealtime(spawnDelay);

        int pointSelected = Random.Range(0, 3); //To use as index for reaching array of spawn points.
        Vector2 pointToSpawn = spawnPoints[pointSelected].transform.position;

        GameObject clonePrefab = Instantiate(monster2, pointToSpawn, Quaternion.identity);

        monsterSprite = clonePrefab.transform.GetChild(0).gameObject;
        if (pointSelected == 1)
            monsterSprite.GetComponent<SpriteRenderer>().flipX = true;
        else
            monsterSprite.GetComponent<SpriteRenderer>().flipX = false;

        monstersCount--;
    }
}

The problem is you are starting a new co-routine every physics tick. I’m not sure why you are using fixed update. You could use a while statement in the coroutine and just start it once. Like so;

using System.Collections;
using UnityEngine;

public class MonsterSpawner : MonoBehaviour
{
    //You may as well use transform here rather than gameobjects
    public Transform[] SpawnPoints;

    public int MonstersCount;

    public GameObject Monster2;

    [SerializeField]
    private float _spawnDelay = 5f;

    private WaitForSecondsRealtime _waitTime;

    private void Start()
    {
        _waitTime = new WaitForSecondsRealtime(_spawnDelay);

        StartCoroutine(SpawnMonster());
    }

    IEnumerator SpawnMonster()
    {
        while (MonstersCount >= 1)
        {
            var pointSelected = Random.Range(0, 3); //To use as index for reaching array of spawn points.
            var pointToSpawn = SpawnPoints[pointSelected].position;

            var clonePrefab = Instantiate(Monster2, pointToSpawn, Quaternion.identity);

            var monsterSprite = clonePrefab.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>();

            if (monsterSprite != null)
            {
                monsterSprite.flipX = pointSelected == 1;
            }

            MonstersCount--;

            yield return _waitTime;
        }

        Destroy(gameObject);
    }
}

You could also use a timer in the update method and do away with the coroutine if you wish or create a method you could call to spawn x monsters whenever you wish rather than destroying the spawner.