Search Unity

Spawning specified amount of objects randomly without collision.

Discussion in 'Scripting' started by CTroyd, Jun 25, 2019.

  1. CTroyd

    CTroyd

    Joined:
    Sep 7, 2018
    Posts:
    3
    Hi,

    I'm trying to get an enemy to be instantiated at a randomized location (Vector3 on z and x axis) around the object and it must first check whether or not there is another object that will collide with it. However i also want to spawn a set amount of objects no matter what.

    My problem is that whenever I try to ensure that the amount of objects spawned is correct with a while/for loop, Unity crashes. I believe this is because the position is being randomized and unity just assumes that it'll never find a valid position.

    Here is my C# Code for the spawning, which causes Unity to freeze:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SpawnTest : MonoBehaviour
    6. {
    7.     public string[] GroupType = new string[] { "Easy", "Normal", "Hard" };
    8.     [HideInInspector]
    9.     public string groupType;
    10.     [HideInInspector]
    11.     public int num = 0;
    12.  
    13.     [HideInInspector]
    14.     public int enemiesToSpawn = 0;
    15.     public GameObject[] enemies;
    16.  
    17.     void Start()
    18.     {
    19.         GenerateGroupType();
    20.         SpawnEnemies();
    21.         Debug.Log("Spawned " + groupType + " pack. \nAt " + transform.position.ToString()
    22.                     + ". " + "\nRoll: " + num.ToString() + "." + "\nPack Size: "
    23.                     + enemiesToSpawn.ToString());
    24.     }
    25.  
    26.     public void GenerateGroupType() // Decides what group type to spawn
    27.     {
    28.         int num = Random.Range(0, 100);
    29.  
    30.         if (num <= 80)
    31.         {
    32.             groupType = GroupType[0];
    33.         }
    34.         else if (num > 80 && num <= 95)
    35.         {
    36.             groupType = GroupType[1];
    37.         }
    38.         else if (num > 95 && num <= 100)
    39.         {
    40.             groupType = GroupType[2];
    41.         }
    42.     }
    43.  
    44.     void SpawnEnemies()
    45.     {
    46.         enemiesToSpawn = Random.Range(6, 10);
    47.         Vector3 spawnPos = new Vector3(Random.Range(-7, 7), 0, Random.Range(-7, 7));
    48.  
    49.         float radius = 1.0f;
    50.         bool bossNotSpawned = true;
    51.  
    52.         for (int i = 0; i < enemiesToSpawn; i++)
    53.         {
    54.             spawnPos = new Vector3(Random.Range(-7, 7), 0, Random.Range(-7, 7));
    55.  
    56.             if (Physics.CheckSphere(spawnPos, radius))
    57.             {
    58.                 i--;
    59.             }
    60.             else
    61.             {
    62.                 if (groupType == "Hard")
    63.                 {
    64.                     if (bossNotSpawned)
    65.                     {
    66.                         Instantiate(enemies[0],
    67.                                     spawnPos,
    68.                                     Quaternion.Euler(new Vector3(0, Random.Range(0, 360), 0)),
    69.                                     gameObject.transform);
    70.  
    71.                         bossNotSpawned = false;
    72.                     }
    73.                     else
    74.                     {
    75.                         Instantiate(enemies[2],
    76.                                     spawnPos,
    77.                                     Quaternion.Euler(new Vector3(0, Random.Range(0, 360), 0)),
    78.                                     gameObject.transform);
    79.                     }
    80.                 }
    81.                 else if (groupType == "Normal")
    82.                 {
    83.                     Instantiate(enemies[1],
    84.                                 spawnPos,
    85.                                 Quaternion.Euler(new Vector3(0, Random.Range(0, 360), 0)),
    86.                                 gameObject.transform);
    87.                 }
    88.                 else if (groupType == "Easy")
    89.                 {
    90.                     Instantiate(enemies[2],
    91.                                 spawnPos,
    92.                                 Quaternion.Euler(new Vector3(0, Random.Range(0, 360), 0)),
    93.                                 gameObject.transform);
    94.                 }
    95.             }
    96.         }
    97.     }
    98. }
    99.  
    This script is attached to an empty Game Object in the scene.

    Any help or tips would be appreciated! :)
     
    Last edited: Jun 25, 2019
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    Assuming it doesn't have a bug in it, then most likely you are running out of places to put the objects.

    The way the code above is written, it will endlessly try even when there is no space available.

    You can handle this by:

    1) increasing the area in which you can place objects (making the ranges larger over time when things fail for too long)

    2) giving up after a certain number of tries.
     
  3. CTroyd

    CTroyd

    Joined:
    Sep 7, 2018
    Posts:
    3
    So if I choose option 2 I can change the for loop to run for ~100 times as an example and if it has spawned the enemies needed then it must just break the loop?

    EDIT: So your method 2 worked for me, however for some reason the Physics.SphereCheck isnt working at some points (I've removed the "i--;"), it is spawning the enemy directly inside of another enemy. I've only had this occur between two enemies in a group and its not consistently happening though.
     
    Last edited: Jun 26, 2019
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    I'm not sure what the physics system does if the points are equal... just track the positions of enemies you spawn in your own list and then do your own compare against every enemy you've already placed, otherwise you'll be forever beholden to whatever quirks there are in the physics system.
     
  5. CTroyd

    CTroyd

    Joined:
    Sep 7, 2018
    Posts:
    3
    Oof, was trying to avoid having to save the Vector's in a random list but I guess its unavoidable. Anyways, appreciate the help! :)