How do I make enemies not spawn in the same position?

So I am making a 3D game which has a perspective of a 2D game and I made an enemy spawner game object and gave it this script. And here’s the problem, sometimes enemies randomly spawn in the same position. How do I prevent this from happening? Thanks for your support!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnEnemy : MonoBehaviour
{
    public GameObject[] enemyPrefabs;
    public Vector3 spawnPos;

    private int enemyCount = 0;

    private float startDelay = 3;
    public float minValuex = -8;
    public float spaceBetweenSquares = 1f;
    private BoxCollider boxCollider;
    private int maxEnemies = 4;

    Vector3[] spawnedEnemiesPosition;

    private PlayerController playerControllerScript;

    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("SpawnEnemies", startDelay, Random.Range(4f, 5f));
        playerControllerScript = GameObject.Find("Player").GetComponent<PlayerController>();

        for (int i = 0; i < maxEnemies; i++)
        {
            spawnedEnemiesPosition *= new Vector3(0, 0, 0);*

}
}

// Update is called once per frame
void Update()
{

}

Vector3 RandomSpawnPosition()
{

float spawnPosX = minValuex + (RandomSquareIndex() * spaceBetweenSquares);
float spawnPosY = 0;

Vector3 spawnPosition = new Vector3(spawnPosX, spawnPosY, -2);

return spawnPosition;
}

// Generates random square index from 0 to 3, which determines which square the target will appear in
int RandomSquareIndex()
{
return Random.Range(-2, 0);
}

void SpawnEnemies()
{
if (playerControllerScript.gameOver == false && enemyCount <= 4)
{
int enemyIndex = Random.Range(0, enemyPrefabs.Length);
spawnPos = RandomSpawnPosition();

//bool CheckBox(Vector3 center = new Vector3(0.009f, 1.26f, -0.033f), Vector3 halfExtents, Quaternion orientation = Quaternion.identity, int layermask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

Instantiate(enemyPrefabs[enemyIndex], spawnPos, enemyPrefabs[enemyIndex].transform.rotation);

enemyCount++;
}
}
}

Easiest way would be to add the position of each enemy to a list when they spawn.

Before an enemy spawns, check each position in the list, and if the proposed spawn position is too close to a position in the list, change the proposed spawn position.

I second Zaeran’s answer, but I’d like to add to it.

Add a List and then add to that anytime you have a new enemy (remove from it when you remove that enemy). Then, when you’re checking for their distances, just use a sample position to test if there is an enemy at the chosen place for the enemy’s next spawn - Loop through all current enemies and test their distances :

if((enemy.position - newSpawnPosition).sqrMagnitude > (some squared value)) continue; else { GenerateNewPosition() }

GenerateNewPosition is just a dummy function here, but it would just call the spawn function again to get a new position to test. You should have some fail safe so you don’t have an endless loop. Perhaps if it fails after 100 times it just stops, because maybe there are too many enemies or something.

I wouldn’t use InvokeRepeating because it’s difficult to control. Try to use controllable loops that you can break anytime. While loops, or maybe forloops. You could also use the Update function to spawn enemies every few seconds.

float nextSpawn, spawnRate = 1;

void Update {
if(Time.time > nextSpawn){
nextSpawn = Time.time + spawnRate;
SpawnEnemy();
}
}

This would spawn an enemy every 1 second. You can utilize Time.time to control the rate of things easily – just have a value that keeps the time, and add the amount of time you want to wait to it.