# Save a random number in an array and refer to it later

Hello. So I’m having some trouble with trying to instantiate from an array randomly, then referring to a specific chosen random number later. There is space for as many random numbers in the ‘randNum’ array I have as the ‘personArray’ GameObject array has at any given time. I should be able to save a chosen random number, then refer to the GameObject the random number generator chose in the array later from the Update function.

I’m trying to refer to it in order to change a tag the GameObject’s prefab has. Here’s a bit of the code I’m using:

``````void SpawnPerson () {

if(current < personArray.Length)
{
current += 1;
} else current = 0;

randNum[current] = RandomGen();

Vector3 randomPosition = new Vector3
(
Random.Range (boundary.xMin, boundary.xMax),
Random.Range (boundary.yMin, boundary.yMax),
-1.25f
);

if(CubeMover.keepClosed == false && personArray[randNum[current]].tag == "Person")
{
guyPerson = Instantiate
(
personArray[randNum[current]],
randomPosition,
Quaternion.identity
)
as GameObject;
}

personArray[randNum[current]].tag = "Spawned";

}

int RandomGen () {

int i;

i = Random.Range(0, personArray.Length);

return i;

}
``````

Thanks.

I got a bit farther in trying to find the solution. I made the ‘guyPerson’ GameObject that is instantiated an array that is as long as the personArray. I now have two arrays. I have a super bulky answer to the whole thing that doesn’t work correctly. Here’s the part that does not work:

``````if(
guyPerson[0].transform.position.y > 4.5f ||
guyPerson[0].transform.position.y < -4.5f ||
guyPerson[0].tag == "Skeleton" ||

guyPerson[1].transform.position.y > 4.5f |
guyPerson[1].transform.position.y < -4.5f |
guyPerson[1].tag == "Skeleton" ||

guyPerson[2].transform.position.y > 4.5f ||
guyPerson[2].transform.position.y < -4.5f ||
guyPerson[2].tag == "Skeleton" ||

guyPerson[3].transform.position.y > 4.5f ||
guyPerson[3].transform.position.y < -4.5f ||
guyPerson[3].tag == "Skeleton" ||

guyPerson[4].transform.position.y > 4.5f ||
guyPerson[4].transform.position.y < -4.5f ||
guyPerson[4].tag == "Skeleton"
)
{
Debug.Log("1st");
if(guyPerson[0])
{
personArray[0].tag = "Person";
}

if(guyPerson[1])
{
personArray[1].tag = "Person";
}

if(guyPerson[2])
{
personArray[2].tag = "Person";
}

if(guyPerson[3])
{
personArray[3].tag = "Person";
}

if(guyPerson[4])
{
personArray[4].tag = "Person";
}
}
``````

The only finds the first GameObject mentioned from the ‘guyPerson’ array. I wonder why it does not recognize anything else but the first GameObject mentioned within the array. I tried separating them as different if statements, but that did not work. I have changed the first mentioned GameObject to second in array and the program still recognizes it for some reason. All tips on getting the thing shorter and to work properly would be highly appreciated.

Ok, I got it working with a new bulky solution. Here’s the whole class:

``````using UnityEngine;
using System.Collections;

public class PersonSpawner : MonoBehaviour {

public GameObject[] personArray;
public Boundary boundary;
public GameObject[] guyPerson;

int current;
int randNum;

bool[] personBool;

void Awake () {

for (int i = 0; i < personArray.Length; i++)
{
personArray[i].tag = "Person";
}

guyPerson = new GameObject[personArray.Length];
personBool = new bool[personArray.Length];

}

void Start () {

InvokeRepeating("SpawnPerson", 0.0f, 1.5f);

}

void Update () {

PositionCheck();

}

void SpawnPerson () {

randNum = RandomGen();

guyPerson[randNum] = GameObject.Find("person" + (randNum + 1) + "(Clone)");

Vector3 randomPosition = new Vector3
(
Random.Range (boundary.xMin, boundary.xMax),
Random.Range (boundary.yMin, boundary.yMax),
-1.25f
);

if(CubeMover.keepClosed == false && personArray[randNum].tag == "Person")
{
guyPerson[randNum] = Instantiate
(
personArray[randNum],
randomPosition,
Quaternion.identity
)
as GameObject;
}

if(personArray[randNum].tag == "Person")
{
personArray[randNum].tag = "Spawned";
personBool[randNum] = true;
}

}

int RandomGen () {

int i;

i = Random.Range(0, personArray.Length);

return i;

}

void PositionCheck () {

if(personBool[0] == true)
{
if(guyPerson[0].transform.position.y > 4.5f ||
guyPerson[0].transform.position.y < -4.5)
{
personArray[0].tag = "Person";
personBool[0] = false;
}
}

if(personBool[1] == true)
{
if(guyPerson[1].transform.position.y > 4.5f ||
guyPerson[1].transform.position.y < -4.5)
{
personArray[1].tag = "Person";
personBool[1] = false;
}
}

if(personBool[2] == true)
{
if(guyPerson[2].transform.position.y > 4.5f ||
guyPerson[2].transform.position.y < -4.5)
{
personArray[2].tag = "Person";
personBool[2] = false;
}
}

if(personBool[3] == true)
{
if(guyPerson[3].transform.position.y > 4.5f ||
guyPerson[3].transform.position.y < -4.5)
{
personArray[3].tag = "Person";
personBool[3] = false;
}
}

if(personBool[4] == true)
{
if(guyPerson[4].transform.position.y > 4.5f ||
guyPerson[4].transform.position.y < -4.5)
{
personArray[4].tag = "Person";
personBool[4] = false;
}
}
}
}
``````

Would still be good to pack the if statements in the PositionCheck function to one, but I’m not quite sure how.

Ok. Here’s the last code you pasted in a refactored version. It should still be logically the same as the code posted, with one exception; the “bulky” PositionCheck in your code checked the first five elements, whereas in the refactoed code it checks the whole personBool array.

``````using UnityEngine;
using System.Collections;

public class PersonSpawner : MonoBehaviour
{
public GameObject[] personArray;
public Boundary boundary;
public GameObject[] guyPerson;

bool[] personBool;

void Awake()
{
for (int i = 0; i < personArray.Length; i++)
{
personArray[i].tag = "Person";
}

guyPerson = new GameObject[personArray.Length];
personBool = new bool[personArray.Length];
}

void Start()
{
InvokeRepeating("SpawnPerson", 0.0f, 1.5f);
}

void Update()
{
for (int i = 0; i < personBool.Length; ++i)
{
var yPosition = guyPerson[i].transform.position.y;
if (yPosition > 4.5f || yPosition < -4.5f)
{
personArray[i].tag = "Person";
personBool[i] = false;
}
}
}

void SpawnPerson()
{
var randNum = Random.Range(0, personArray.Length);
guyPerson[randNum] = GameObject.Find("person" + (randNum + 1) + "(Clone)");
Vector3 randomPosition = new Vector3
(
Random.Range(boundary.xMin, boundary.xMax),
Random.Range(boundary.yMin, boundary.yMax),
-1.25f
);

var person = personArray[randNum];
if (person.tag == "Person")
{
if (CubeMover.keepClosed)
{
guyPerson[randNum] = Instantiate(person, randomPosition, Quaternion.identity) as GameObject;
}

person.tag = "Spawned";
personBool[randNum] = true;
}
}
}
``````

Hmm, the for loop in Update is not switching the tag from ‘Spawned’ to ‘Person’.

It’s the same probem I had with the previous if statement things that were not limited by the boolean. I have an array that is empty to begin with (which fills up with the persons as they spawn) and the entrance must be limited by the boolean, because it seems like if it isn’t the code stops running through the given function as it bumps into the empty place in the array. Seems like that same thing is stopping the for loop from completing like it is supposed to. Really weird that it works that way to be honest!

EDIT: Ok, I added the ‘if boolean = true’ to the for loop and changed the ‘if(CubeMover.keepClosed)’ back to ‘if(CubeMover.keepClosed == false)’. For some reason it didn’t work without the ‘== false’ part, but now it works perfectly. A huge thank you for the answer! I still wonder… What does the ‘if(CubeMover.keepClosed)’ mean?

Here’s the code:

``````using UnityEngine;
using System.Collections;

public class PersonSpawner : MonoBehaviour {

public GameObject[] personArray;
public Boundary boundary;
public GameObject[] guyPerson;

bool[] personBool;

float min = -9.5f;
float max = 9.5f;

void Awake () {

for (int i = 0; i < personArray.Length; i++)
{
personArray[i].tag = "Person";
}

guyPerson = new GameObject[personArray.Length];
personBool = new bool[personArray.Length];

}

void Start () {

InvokeRepeating("SpawnPerson", 0.0f, 1.5f);

}

void Update () {

for (int i = 0; i < personBool.Length; ++i)
{
if(personBool[i] == true)
{
var yPosition = guyPerson[i].transform.position.y;
if (yPosition > max|| yPosition < min)
{
personArray[i].tag = "Person";
personBool[i] = false;
}
}
}
}

void SpawnPerson () {

int randNum = RandomGen();

guyPerson[randNum] = GameObject.Find("person" + (randNum + 1) + "(Clone)");

Vector3 randomPosition = new Vector3
(
Random.Range (boundary.xMin, boundary.xMax),
Random.Range (boundary.yMin, boundary.yMax),
-1.25f
);

if(personArray[randNum].tag == "Person")
{
if(CubeMover.keepClosed == false)
{
guyPerson[randNum] = Instantiate
(
personArray[randNum],
randomPosition,
Quaternion.identity
)
as GameObject;
}

personArray[randNum].tag = "Spawned";
personBool[randNum] = true;

}
}

int RandomGen () {

int i;

i = Random.Range(0, personArray.Length);

return i;

}
}
``````

Oh, my bad. I did change the logic when refactoring your code. It should’ve been “CubeMover.keepClosed == false”. Seems like I deleted a bit too much.

I’m curious why you insist of keeping the “RandomGen ()” method though?

Haha good catch, not sure actually. It’s definitely a bit redundant. I kind of combined your code into mine and didn’t remember to take the RandomGen method out. Took the method out now.