Search Unity

Question Trying to spawn multiple objects at once without spawning in same location

Discussion in 'Scripting' started by bettsmatthew, May 1, 2023.

  1. bettsmatthew

    bettsmatthew

    Joined:
    Oct 7, 2022
    Posts:
    4
    I am working on a slot machine type game in which 9 icons spawn at one of 9 fixed locations. when the play button is pressed and then drop down landing in fixed locations. I can spawn icons when I press play but it spawns one at a time and will spawn at the same location. For this I am really just looking for some guidance on stopping multiple icons spawning at the same location. I will figure out the spawning 9 randomly at once without repeating the same icon. Posting what I have so far.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class SpawnController : MonoBehaviour
    7. {
    8.     // Play Button GameObject reference
    9.     public GameObject playButton;
    10.  
    11.     // Icon Prefab
    12.     public GameObject[] iconPrefab;
    13.     public Vector3[] spawnPrefab;
    14.  
    15.     // Disable spawn
    16.     public bool canSpawn = true;
    17.  
    18.  
    19.  
    20.     /*
    21.         // Spawn locations on board
    22.         // Top left of board
    23.         public Vector3 spawnOne = new Vector3(-2, 14, 750);
    24.         // Top middle of board
    25.         public Vector3 spawnTwo = new Vector3(1, 14, 750);
    26.         // Top right of board
    27.         public Vector3 spawnThree = new Vector3(4, 14, 750);
    28.         // Middle left of board
    29.         public Vector3 spawnFour = new Vector3(-2, 11, 750);
    30.         // Middle middle of board
    31.         public Vector3 spawnFive = new Vector3(1, 11, 750);
    32.         // Middle right of board
    33.         public Vector3 spawnSix = new Vector3(4, 11, 750);
    34.         // Bottom left of board
    35.         public Vector3 spawnSeven = new Vector3(-2, 8, 750);
    36.         // Bottom middle of board
    37.         public Vector3 spawnEight = new Vector3(-1, 8, 750);
    38.         // Bottom right of board
    39.         public Vector3 spawnNine = new Vector3(4, 8, 750);
    40.     */
    41.  
    42.     void Update()
    43.     {
    44.  
    45.  
    46.         if (Input.GetKeyDown(KeyCode.Space))
    47.         {
    48.        
    49.             int iconIndex = Random.Range(0, 9);
    50.             int spawnIndex = Random.Range(0,9);
    51.  
    52.             Instantiate(iconPrefab[iconIndex], spawnPrefab[spawnIndex],
    53.                               iconPrefab[iconIndex].transform.rotation);
    54.              
    55.         }
    56.     }
    57.  
    58.  
    59. }
    60.  
    61.  
    62.  
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    First off rather than using magic hardcoded numbers like this:
    Code (CSharp):
    1. int iconIndex = Random.Range(0, 9);
    2. int spawnIndex = Random.Range(0,9);
    It's better to use your actual array lengths. This will reduce the risk for bugs, make the code easier to read, and make it expandable if you want to add or remove stuff:
    Code (CSharp):
    1. int iconIndex = Random.Range(0, iconPrefab.Length);
    2. int spawnIndex = Random.Range(0,spawnPrefab.Length);
    Now aside from that, the code should work as long as you have properly populated the vectors in the inspector.
     
    bettsmatthew likes this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
  4. bettsmatthew

    bettsmatthew

    Joined:
    Oct 7, 2022
    Posts:
    4

    I will give this a shot, thank you so much for your time and assistance!
     
  5. bettsmatthew

    bettsmatthew

    Joined:
    Oct 7, 2022
    Posts:
    4
    So icons will still spawn in the same location, but it did clean my code up!
     
  6. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    When there are preset spawn spots, the normal way of getting random-without-repeats is to do a "shuffle". Create an array filled with integers 0 to 8 and run a shuffle algorithm (easy to look up and easy to paste or type) to get 0 to 8 randomly. If you want to spawn 5 items, use the first 5 values. Code to get the random spots will look like
    SpawnLocations[ R[n] ]
    -- if the first shuffled value, R[0], is 4, this gives SpawnLocations[4] for the first thing.
     
    Last edited: May 1, 2023
    PraetorBlue and bettsmatthew like this.
  7. bettsmatthew

    bettsmatthew

    Joined:
    Oct 7, 2022
    Posts:
    4
    Thank you, I will look into this as well! I appreciate your time in giving a response!
     
  8. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    Well, you do use Random.Range each try, this means you can end up using same Random number multiples times. If you want to be sure each position is used only once, you need to remove it from your array choice after it has been picked.

    Code (CSharp):
    1.  
    2.  
    3.    List<Vector3> spawnPositions = new List<Vector3>(){ new Vector3(0, 0, 0), new Vector3(1, 1, 1) };
    4.  
    5. ...
    6.  
    7.     int random = Random.Range(0, spawnPositions.Count);
    8.     Vector3 position = spawnPositions[random];
    9.     p.RemoveAt(random);
    10.  
    11.     Instantiate(iconPrefab[iconIndex], position, iconPrefab[random].transform.rotation);
    12.  
    13.  
    Note I used the generated random to also pick the icon to use, as both your list use same length and I assumed you want only one of each icon to be displayed too
     
    Last edited: May 1, 2023
  9. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    Often you don't want to mutilate the list, for example, it's actually a series of empties, or came pre-made in the Inspector, or was from a file. Pre-making a random set of shuffled 0-8's handles cases like this. Since many people have a shuffle in their library already, it's not much code. In the end the "shuffle" method is often seen as just superior to the "remove used values" method.