Search Unity

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

Discussion in 'Scripting' started by matias-e, Apr 8, 2015.

  1. matias-e

    matias-e

    Joined:
    Sep 29, 2014
    Posts:
    106
    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:

    Code (CSharp):
    1. void SpawnPerson () {
    2.  
    3.         if(current < personArray.Length)
    4.         {
    5.         current += 1;
    6.         } else current = 0;
    7.  
    8.         randNum[current] = RandomGen();
    9.  
    10.         Vector3 randomPosition = new Vector3
    11.             (
    12.                 Random.Range (boundary.xMin, boundary.xMax),
    13.                 Random.Range (boundary.yMin, boundary.yMax),
    14.                 -1.25f
    15.             );
    16.  
    17.         if(CubeMover.keepClosed == false && personArray[randNum[current]].tag == "Person")
    18.         {
    19.             guyPerson = Instantiate
    20.                 (
    21.                     personArray[randNum[current]],
    22.                     randomPosition,
    23.                     Quaternion.identity
    24.                 )
    25.                     as GameObject;
    26.         }
    27.  
    28.         personArray[randNum[current]].tag = "Spawned";
    29.  
    30.     }
    31.  
    32.  
    33.     int RandomGen () {
    34.  
    35.         int i;
    36.  
    37.         i = Random.Range(0, personArray.Length);
    38.  
    39.         return i;
    40.  
    41.     }          
    42.  
    Thanks.
     
  2. matias-e

    matias-e

    Joined:
    Sep 29, 2014
    Posts:
    106
    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:

    Code (CSharp):
    1. if(
    2.            guyPerson[0].transform.position.y > 4.5f ||
    3.            guyPerson[0].transform.position.y < -4.5f ||
    4.            guyPerson[0].tag == "Skeleton" ||
    5.  
    6.            guyPerson[1].transform.position.y > 4.5f |
    7.            guyPerson[1].transform.position.y < -4.5f |
    8.            guyPerson[1].tag == "Skeleton" ||
    9.  
    10.            guyPerson[2].transform.position.y > 4.5f ||
    11.            guyPerson[2].transform.position.y < -4.5f ||
    12.            guyPerson[2].tag == "Skeleton" ||
    13.  
    14.            guyPerson[3].transform.position.y > 4.5f ||
    15.            guyPerson[3].transform.position.y < -4.5f ||
    16.            guyPerson[3].tag == "Skeleton" ||
    17.  
    18.            guyPerson[4].transform.position.y > 4.5f ||
    19.            guyPerson[4].transform.position.y < -4.5f ||
    20.            guyPerson[4].tag == "Skeleton"
    21.           )
    22.         {
    23.             Debug.Log("1st");
    24.             if(guyPerson[0])
    25.             {
    26.                 personArray[0].tag = "Person";
    27.             }
    28.  
    29.             if(guyPerson[1])
    30.             {
    31.                 personArray[1].tag = "Person";
    32.             }
    33.  
    34.             if(guyPerson[2])
    35.             {
    36.                 personArray[2].tag = "Person";
    37.             }
    38.  
    39.             if(guyPerson[3])
    40.             {
    41.                 personArray[3].tag = "Person";
    42.             }
    43.  
    44.             if(guyPerson[4])
    45.             {
    46.                 personArray[4].tag = "Person";
    47.             }
    48.         }
    49.  
    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.
     
    Last edited: Apr 8, 2015
  3. matias-e

    matias-e

    Joined:
    Sep 29, 2014
    Posts:
    106
    Ok, I got it working with a new bulky solution. Here's the whole class:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PersonSpawner : MonoBehaviour {
    5.  
    6.     public GameObject[] personArray;
    7.     public Boundary boundary;
    8.     public GameObject[] guyPerson;
    9.  
    10.     int current;
    11.     int randNum;
    12.  
    13.     bool[] personBool;
    14.  
    15.     void Awake () {
    16.  
    17.         personArray = Resources.LoadAll<GameObject>("Persons");
    18.         for (int i = 0; i < personArray.Length; i++)
    19.         {
    20.             personArray[i].tag = "Person";
    21.         }
    22.  
    23.         guyPerson = new GameObject[personArray.Length];
    24.         personBool = new bool[personArray.Length];
    25.  
    26.     }
    27.  
    28.     void Start () {
    29.  
    30.         InvokeRepeating("SpawnPerson", 0.0f, 1.5f);
    31.      
    32.     }
    33.  
    34.     void Update () {
    35.  
    36.         PositionCheck();
    37.  
    38.     }
    39.  
    40.     void SpawnPerson () {
    41.  
    42.         randNum = RandomGen();
    43.  
    44.         guyPerson[randNum] = GameObject.Find("person" + (randNum + 1) + "(Clone)");
    45.      
    46.         Vector3 randomPosition = new Vector3
    47.             (
    48.                 Random.Range (boundary.xMin, boundary.xMax),
    49.                 Random.Range (boundary.yMin, boundary.yMax),
    50.                 -1.25f
    51.             );
    52.  
    53.         if(CubeMover.keepClosed == false && personArray[randNum].tag == "Person")
    54.         {
    55.             guyPerson[randNum] = Instantiate
    56.                 (
    57.                     personArray[randNum],
    58.                     randomPosition,
    59.                     Quaternion.identity
    60.                 )
    61.                     as GameObject;  
    62.         }
    63.  
    64.         if(personArray[randNum].tag == "Person")
    65.         {
    66.         personArray[randNum].tag = "Spawned";
    67.         personBool[randNum] = true;
    68.         }
    69.  
    70.  
    71.     }
    72.  
    73.  
    74.     int RandomGen () {
    75.  
    76.         int i;
    77.  
    78.         i = Random.Range(0, personArray.Length);
    79.  
    80.         return i;
    81.  
    82.     }
    83.  
    84.     void PositionCheck () {
    85.  
    86.         if(personBool[0] == true)
    87.         {
    88.             if(guyPerson[0].transform.position.y > 4.5f ||
    89.                guyPerson[0].transform.position.y < -4.5)
    90.             {
    91.                 personArray[0].tag = "Person";
    92.                 personBool[0] = false;
    93.             }
    94.         }
    95.  
    96.         if(personBool[1] == true)
    97.         {
    98.             if(guyPerson[1].transform.position.y > 4.5f ||
    99.                guyPerson[1].transform.position.y < -4.5)
    100.             {
    101.                 personArray[1].tag = "Person";
    102.                 personBool[1] = false;
    103.             }
    104.         }
    105.  
    106.         if(personBool[2] == true)
    107.         {
    108.             if(guyPerson[2].transform.position.y > 4.5f ||
    109.                guyPerson[2].transform.position.y < -4.5)
    110.             {
    111.                 personArray[2].tag = "Person";
    112.                 personBool[2] = false;
    113.             }
    114.         }
    115.  
    116.         if(personBool[3] == true)
    117.         {
    118.             if(guyPerson[3].transform.position.y > 4.5f ||
    119.                guyPerson[3].transform.position.y < -4.5)
    120.             {
    121.                 personArray[3].tag = "Person";
    122.                 personBool[3] = false;
    123.             }
    124.         }
    125.  
    126.         if(personBool[4] == true)
    127.         {
    128.             if(guyPerson[4].transform.position.y > 4.5f ||
    129.                guyPerson[4].transform.position.y < -4.5)
    130.             {
    131.                 personArray[4].tag = "Person";
    132.                 personBool[4] = false;
    133.             }
    134.         }
    135.     }
    136. }
    Would still be good to pack the if statements in the PositionCheck function to one, but I'm not quite sure how.
     
  4. Sabo

    Sabo

    Joined:
    Nov 7, 2009
    Posts:
    151
    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.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PersonSpawner : MonoBehaviour
    5. {
    6.     public GameObject[] personArray;
    7.     public Boundary boundary;
    8.     public GameObject[] guyPerson;
    9.  
    10.     bool[] personBool;
    11.  
    12.     void Awake()
    13.     {
    14.         personArray = Resources.LoadAll<GameObject>("Persons");
    15.         for (int i = 0; i < personArray.Length; i++)
    16.         {
    17.             personArray[i].tag = "Person";
    18.         }
    19.  
    20.         guyPerson = new GameObject[personArray.Length];
    21.         personBool = new bool[personArray.Length];
    22.     }
    23.  
    24.     void Start()
    25.     {
    26.         InvokeRepeating("SpawnPerson", 0.0f, 1.5f);
    27.     }
    28.  
    29.     void Update()
    30.     {
    31.         for (int i = 0; i < personBool.Length; ++i)
    32.         {
    33.             var yPosition = guyPerson[i].transform.position.y;
    34.             if (yPosition > 4.5f || yPosition < -4.5f)
    35.             {
    36.                 personArray[i].tag = "Person";
    37.                 personBool[i] = false;
    38.             }
    39.         }
    40.     }
    41.  
    42.     void SpawnPerson()
    43.     {
    44.         var randNum = Random.Range(0, personArray.Length);
    45.         guyPerson[randNum] = GameObject.Find("person" + (randNum + 1) + "(Clone)");
    46.         Vector3 randomPosition = new Vector3
    47.             (
    48.                 Random.Range(boundary.xMin, boundary.xMax),
    49.                 Random.Range(boundary.yMin, boundary.yMax),
    50.                 -1.25f
    51.             );
    52.  
    53.         var person = personArray[randNum];
    54.         if (person.tag == "Person")
    55.         {
    56.             if (CubeMover.keepClosed)
    57.             {
    58.                 guyPerson[randNum] = Instantiate(person, randomPosition, Quaternion.identity) as GameObject;
    59.             }
    60.  
    61.             person.tag = "Spawned";
    62.             personBool[randNum] = true;
    63.         }
    64.     }
    65. }
     
  5. matias-e

    matias-e

    Joined:
    Sep 29, 2014
    Posts:
    106
    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:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PersonSpawner : MonoBehaviour {
    5.  
    6.     public GameObject[] personArray;
    7.     public Boundary boundary;
    8.     public GameObject[] guyPerson;
    9.  
    10.     bool[] personBool;
    11.  
    12.     float min = -9.5f;
    13.     float max = 9.5f;
    14.  
    15.     void Awake () {
    16.  
    17.         personArray = Resources.LoadAll<GameObject>("Persons");
    18.         for (int i = 0; i < personArray.Length; i++)
    19.         {
    20.             personArray[i].tag = "Person";
    21.         }
    22.  
    23.         guyPerson = new GameObject[personArray.Length];
    24.         personBool = new bool[personArray.Length];
    25.  
    26.     }
    27.  
    28.     void Start () {
    29.  
    30.         InvokeRepeating("SpawnPerson", 0.0f, 1.5f);
    31.  
    32.     }
    33.  
    34.     void Update () {
    35.  
    36.         for (int i = 0; i < personBool.Length; ++i)
    37.         {
    38.             if(personBool[i] == true)
    39.             {
    40.                 var yPosition = guyPerson[i].transform.position.y;
    41.                 if (yPosition > max|| yPosition < min)
    42.                 {
    43.                     personArray[i].tag = "Person";
    44.                     personBool[i] = false;
    45.                 }
    46.             }
    47.         }
    48.     }
    49.  
    50.     void SpawnPerson () {
    51.  
    52.         int randNum = RandomGen();
    53.  
    54.         guyPerson[randNum] = GameObject.Find("person" + (randNum + 1) + "(Clone)");
    55.  
    56.         Vector3 randomPosition = new Vector3
    57.             (
    58.                 Random.Range (boundary.xMin, boundary.xMax),
    59.                 Random.Range (boundary.yMin, boundary.yMax),
    60.                 -1.25f
    61.             );
    62.  
    63.         if(personArray[randNum].tag == "Person")
    64.         {
    65.             if(CubeMover.keepClosed == false)
    66.             {
    67.             guyPerson[randNum] = Instantiate
    68.                 (
    69.                     personArray[randNum],
    70.                     randomPosition,
    71.                     Quaternion.identity
    72.                 )
    73.                     as GameObject;
    74.             }
    75.  
    76.             personArray[randNum].tag = "Spawned";
    77.             personBool[randNum] = true;
    78.  
    79.         }
    80.     }
    81.  
    82.  
    83.     int RandomGen () {
    84.  
    85.         int i;
    86.  
    87.         i = Random.Range(0, personArray.Length);
    88.  
    89.         return i;
    90.  
    91.     }
    92. }
    93.  
     
    Last edited: Apr 8, 2015
  6. Sabo

    Sabo

    Joined:
    Nov 7, 2009
    Posts:
    151
    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?
     
  7. matias-e

    matias-e

    Joined:
    Sep 29, 2014
    Posts:
    106
    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.