Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question How to get the game to attempt spawning enemies again when a spawnpoint is unavailable?

Discussion in 'Scripting' started by ElateTugboat, Apr 2, 2024.

  1. ElateTugboat

    ElateTugboat

    Joined:
    Jan 4, 2024
    Posts:
    6
    Hello,
    So for a current game that I am working on, I have it setup in a way where there are 12 different spawnpoints, each used to spawn an enemy. Right now it checks for any collision with an enemy, and if there is one it destroys the spawnpoint object so no new enemy can spawn on it. The only problem is I get the error of "The object of type 'Transform' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object" whenever the game attempts to spawn an enemy on the destroyed spawnpoint. If I did not destroy the spawnpoint, then I would get duplicate enemies on the same place which is not what I want. Is there any way I can make the game try multiple times to check for a spawnpoint that isn't destroyed?

    Here is my code for the spawning command:
    Code (CSharp):
    1. public class EnemySpawn : MonoBehaviour
    2. {
    3.     public Transform[] spawnPoints;
    4.     public GameObject[] enemyPrefabs;
    5.     public bool validSpawn;
    6.  
    7.     void Start()
    8.     {
    9.  
    10.     }
    11.  
    12.     void Update()
    13.     {
    14.         if (Input.GetMouseButtonDown(0))
    15.         {
    16.             int randEnemy = Random.Range(0, enemyPrefabs.Length);
    17.             int randSpawnPoint = Random.Range(0, spawnPoints.Length);
    18.             Instantiate(enemyPrefabs[randEnemy], spawnPoints[randSpawnPoint].position, transform.rotation);
    19.         }
    20.     }
    21. }
    Additionally, here is the code I have for each of my spawnpoints when they need to be destroyed:
    Code (CSharp):
    1. public class SpawnValidity : MonoBehaviour
    2. {
    3.     public bool validSpawn;
    4.     void Start()
    5.     {
    6.         validSpawn = true;
    7.     }
    8.     void Update()
    9.     {
    10.         if (validSpawn == false)
    11.         {
    12.             Destroy(gameObject);
    13.         }
    14.     }
    15.     private void OnCollisionEnter2D(Collision2D other)
    16.     {
    17.         if (other.gameObject.CompareTag("Enemy"))
    18.         {
    19.             validSpawn = false;
    20.         }
    21.     }
    22. }
    The attached picture is my main scene; the green points are the spawnpoints. Disregard the blue triangle, that was just a test. My apologies if everything is messy, this is my first project.
    Screenshot 2024-04-01 194014.png
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,240
    The extra component is unnecessary. As you're picking a transform to spawn at, you can use that to remove it from the possible spawn points, and destroy it at the same time. To do this you'll want to use a List<T> as opposed to an array, as well.

    Like so:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class EnemySpawn : MonoBehaviour
    5. {
    6.    public List<Transform> randomSpawnPoints;
    7.    public GameObject[] enemyPrefabs;
    8.  
    9.    void Update()
    10.    {
    11.        if (Input.GetMouseButtonDown(0))
    12.        {
    13.            int randEnemyIndex = Random.Range(0, enemyPrefabs.Length);
    14.            int randomSpawnPointIndex = Random.Range(0, randomSpawnPoints.Count);
    15.  
    16.            GameObject randomEnemy = enemyPrefabs[randEnemyIndex];
    17.  
    18.            Transform randomSpawnPoint = randomSpawnPoints[randomSpawnPointIndex];
    19.            Vector3 spawnPosition = randomSpawnPoint.position;
    20.            Quaternion spawnRotation = randomSpawnPoint.rotation;
    21.  
    22.            Instantiate(randomEnemy, spawnPosition, spawnRotation);
    23.  
    24.            randomSpawnPoints.RemoveAt(randomSpawnPointIndex);
    25.            Destroy(randomSpawnPoint.gameObject);
    26.        }
    27.    }
    28. }
    Also spaced out the code to be more readable.
     
    Last edited: Apr 2, 2024
  3. ElateTugboat

    ElateTugboat

    Joined:
    Jan 4, 2024
    Posts:
    6
    Thanks for the response, however I do get a couple of errors, "randomSpawnPoint[randomSpawnPointIndex]" tells me that randomSpawnPoint is an unassigned local variable, and that I "Cannot apply indexing with [] to an expression of type 'Transform.'" Also, it says that Quaterion cannot be found.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,240
    I wrote it in notepad on my lunch break so there was a few typos. I've fixed up the above code.

    Ideally you don't just blindly copy code but try to understand the principles it's expressing.
     
    MelvMay likes this.
  5. ElateTugboat

    ElateTugboat

    Joined:
    Jan 4, 2024
    Posts:
    6
    No worries, I tried again and it works great. Thanks for the help, I'll keep that tip in mind for the future :)
     
    spiney199 likes this.