- Home /
How to stop multiples of game objects instantiating when using random.range with an array
I am new to scripting and I find it very hard to grasp. I have a project for an internship for my game design skills but this also means I have to do some scripting to complete certain tasks. I have the grasp of most things I need but arrays and loops are not my friends. This is my problem. I instantiate six objects randomly from an array of game objects. This works fine but I frequently get the same object instantiated twice or more. I have searched all the questions in unity and Googled all sorts of word combinations but they all seem to involve integers and numbers printed out not actual game objects.I know I have to use a for loop but I'm not sure where to start. This is the section of code I need to add to I know but I'm not quite sure how.
function LeftChoices()
{
objArray = new GameObject[6];
for (var i : int = 0 ; i < 6 ; i++)
{
objArray[i] = Instantiate(leftObjArray[Random.Range(0,leftObjArray.Length)], posArray[i] , Quaternion.identity);
}
}
If someone could give me a hand that would be absolutely awesome. Many thanks in advance.
$$anonymous$$ove Random.Range outside of Instantiate(), make it var myNum = Random.Range, then check to see if GameObj[myNum] is already in objArray.
So you always want to instantiate six objects irrespective of the array size?
You don't want to get the same random twice (like 1,2,1) or twice in a row (like 1,1)?
In order of responses; Response 1: I'm not sure how that would work as it's the instantiate I'm applying the random.range to, could you please explain in a bit more detail. Response 2: Yes I always want to instantiate 6 objects and I don't want to get the same random at all (like 1,6,4,21,19,8). The six objects are chosen from an array of 21 objects.
Answer by robhuhn · Sep 04, 2013 at 08:45 AM
I made an example where a function GetUniqueRandom stores all previous random numbers in a list and returns the new unique number:
var rndsList : List.<int> = new List.<int>();
function GetUniqueRandom(min : int, max : int) : int
{
var rnd : int; //define an int to store the rnd number
do //the do-while loop will perform one loop at minimum and further loops if the while-condition is met
{
rnd = Random.Range(min, max); //generate a random
}while(rndsList.IndexOf(rnd) != -1); //run another loop (generate a new number) if the list already contains this number
rndsList.Add(rnd); //store the valid number
return rnd; //return the number
}
Then call the method from LeftChoices
for (var i : int = 0 ; i < 6 ; i++)
{
objArray[i] = Instantiate(leftObjArray[GetUniqueRandom(0,leftObjArray.Length)], posArray[i] , Quaternion.identity);
}
I'm not used to UnityScript so there might be a shorter way.
This requires adding
import System.Collections.Generic;
at the beginning of the script.
@robhuhn answer is good enough, but I would slightly change it. Ins$$anonymous$$d of retrying generation of random number if it is already in the list, below code simply adds 1 to it or reverts to $$anonymous$$ in case when max is reached:
function GetUniqueRandom($$anonymous$$ : int, max : int) : int
{
var rnd : int = Random.Range($$anonymous$$, max);
while (rndsList.Contains(rnd))
{
rnd = rnd == max - 1 ? $$anonymous$$ : rnd + 1;
}
rndsList.Add(rnd);
return rnd;
}
Thanks for the responses I thought I would try robhuhns answer first. I tried this and when I saved I got this warning.
Assets/Scripts/ObjectChoices.js(53,10): BCW0023: WARNING: This method could return default value implicitly.
This is the line it was referring to
function GetUniqueRandom($$anonymous$$ : int, max : int) : int
Then when I ran it I continued to get duplicates and I got this warning
Assets/Scripts/ObjectChoices.js(63,16): BCW0015: WARNING: Unreachable code detected.
This is the line it was referring to
LeftChoices();
I don't know why it says this line is unreachable code. This is the whole script as it is now with the warnings.
#pragma strict
import System.Collections.Generic;
var rndsList : List.<int> = new List.<int>();
var leftObjArray : GameObject[];
var rightObjArray : GameObject[];
var posArray : Vector3[];
var objArray : GameObject[];
var posArray1 : Vector3[];
var objArray1 : GameObject[];
var Texture1 : Texture;
var TextureButton: Texture;
function Start ()
{
LeftChoices();
RightChoices();
}
function GetUniqueRandom($$anonymous$$ : int, max : int) : int
{
var rnd : int;
do
{
rnd = Random.Range($$anonymous$$, max);
}
while(rndsList.IndexOf(rnd) != -1);
rndsList.Add(rnd);
return rnd;
LeftChoices();
}
function LeftChoices()
{
objArray = new GameObject[6];
for (var i : int = 0 ; i < 6 ; i++)
{
objArray[i] = Instantiate(leftObjArray[Random.Range(0,leftObjArray.Length)], posArray[i] , Quaternion.identity);
}
}
function RightChoices()
{
objArray1 = new GameObject[4];
for (var f : int = 0 ; f < 4 ; f++)
{
objArray1[f] = Instantiate(rightObjArray[Random.Range(0,rightObjArray.Length)], posArray1[f] , Quaternion.identity);
}
}
function OnGUI()
{
if(GUI.Button(Rect((Screen.width/2)-300,500,50,50), TextureButton,"Label"))
{
//objArray = null;
//print("ta da" );
LeftChoices();
}
}
The objArray = null line is where I'm trying to remove the items from the objarray and put new objects in.
If anyone can tell me what I'm doing wrong with this script it would be most appreciated. I'm completely useless when it comes to scripting.
I tried ArkaneXs solution and the warnings cleared up but I still have duplicates of game objects instantiating. I know it's probably something simple but I'm getting frustrated with this not working.
I have just saved a different script and the above warnings are back could someone please explain what they mean.
The unreachable code in your script is here:
function GetUniqueRandom($$anonymous$$ : int, max : int) : int
{
var rnd : int;
do
{
rnd = Random.Range($$anonymous$$, max);
}
while(rndsList.IndexOf(rnd) != -1);
rndsList.Add(rnd);
return rnd; //when the method has something returned it is done and nothing below will be executed
LeftChoices(); //unreachable code - delete this line
}
And you didn't change this
objArray[i] = Instantiate(leftObjArray[Random.Range(0,leftObjArray.Length)], posArray[i] , Quaternion.identity);
to this
objArray[i] = Instantiate(leftObjArray[GetUniqueRandom(0,leftObjArray.Length)], posArray[i] , Quaternion.identity);
So GetUniqueRandom is never called.
Cool thankyou that solved the issue I thought I had to call the left choices function and now I have no duplicates now I'm actually calling the random function. Thankyou so much.
Your answer

Follow this Question
Related Questions
Random.Range Spawner 1 Answer
Generate random number per function call? 1 Answer
Have random.range anims access float speed variable 0 Answers
Color GUILayout Buttons from Array of Colors (C#) 2 Answers
randomize a function from a array (C#) 3 Answers