Search Unity

Random.Range within a For Loop, disaster.

Discussion in 'Scripting' started by RJ-MacReady, Oct 24, 2014.

  1. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    Code (CSharp):
    1.  
    2. for (int i = 0; i < Slot.Length; i++)
    3.         {
    4.             Random.seed = i * i;
    5.             Slot[i].Quantity = Random.Range(0,100);
    6.         }
    7.  
    The "random" numbers are: 33, 33, 33, 99, 33, 33, 99, 99, 33.

    It's not a one time thing, each time two numbers are returned. To be fair, those two numbers are returned randomly. :)

    I have read the docs, Googled the documentation and I don't think it's broken... I know I'm missing the concept here.
     
  2. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    Nobody? This doesn't seem like it should be difficult...
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Don't set the random seed; you only set the random seed if you specifically want repeatable numbers (and even then you wouldn't set it in a loop like that, you'd just set it once). So just get rid of that line entirely.

    --Eric
     
  4. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    Code (CSharp):
    1. for (int i = 0; i < Slot.Length; i++)
    2. Slot[i].Quantity = Random.Range(0,100);
    Produces the sequence:

    36, 23, 36, 23, 36, 23, 23, 36

    next run

    73, 77, 73, 77, 77, 73, 77, 73, 73
     
  5. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    So what am I missing?

    I believe it's related to time, but I'm not sure in what manner.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Get rid of anything anywhere that sets the seed. Maybe restart Unity.

    --Eric
     
  7. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    I'll try the restart, since I have no other places where I modify seed. In fact, I didn't know you could set the seed until a half hour ago.
     
  8. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    61, 45, 45, 61, 61, 45, 61, 45, 45
    UnityEngine.Debug:Log(Object)
    Inventory:Start() (at Assets/Inventory.cs:53)

    I'm not even using the values for anything, I'm concatenating them to a string and then printing it right after the loop ends. Same result after the restart.

    Is it because random.range uses a time seed?
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Code (csharp):
    1. for (var i = 0; i < 9; i++) {
    2.     Debug.Log (Random.Range(0,100));
    3. }
    Produced 60, 16, 79, 47, 23, 73, 41, 92, 10 here, but that's just random, and it produces different results every time.

    --Eric
     
  10. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    ;_;

    It's my own dumb @$$ fault. I can't believe I did this... but I am using static references, not even thinking about it.. I'm modifying 2 static objects via references, so the numbers are only reflecting the last value set to each of the 2 static objects.
     
    Last edited: Oct 24, 2014
    Harinezumi likes this.
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Well, better that than your computer achieving sentience and deciding to choose specific numbers for itself instead of random ones. ;)

    --Eric
     
  12. RJ-MacReady

    RJ-MacReady

    Joined:
    Jun 14, 2013
    Posts:
    1,718
    Yeah that was freaking me out...
     
  13. clamum

    clamum

    Joined:
    May 14, 2017
    Posts:
    61
    Huh, I'm actually seeing the same sort of thing with Random.Next() calls I have in a while loop (it repeats 10 times, currently). I'm using it to randomly pick a prefab to instantiate in my game and it's picking the same prefab every time.

    I also think it's related to time because if I step through the code it does not repeat values and picks different ones every time, but with no debug and hitting Play on the game, running normal speed, it's the same value it produces.

    I'm not using static references either. I've attached the method code in question.

    Code (CSharp):
    1. private void SpawnPeople()
    2.     {
    3.         while (spawnedPeople.Count < 10)
    4.         {
    5.             System.Random randomPrefabIndex = new System.Random();
    6.             System.Random randomXCoordinate = new System.Random();
    7.             System.Random randomZCoordinate = new System.Random();
    8.      
    9.             int randomPeoplePrefabIndex = randomPrefabIndex.Next(0, peoplePrefabs.Count - 1);
    10.             int randomPeopleXCoordinate = randomXCoordinate.Next(-40, -35);
    11.             int randomPeopleZCoordinate = randomZCoordinate.Next(-50, -10);
    12.  
    13.             // get a random person prefab to spawn
    14.             GameObject randomPersonPrefab = peoplePrefabs.ElementAt(randomPeoplePrefabIndex);
    15.  
    16.             GameObject personGameObject = Instantiate(randomPersonPrefab, new Vector3((float)randomPeopleXCoordinate, -0.21f, (float)randomPeopleZCoordinate), new Quaternion());
    17.             spawnedPeople.Add(personGameObject);
    18.         }
    19.     }
     
  14. ZO5KmUG6R

    ZO5KmUG6R

    Joined:
    Jul 15, 2010
    Posts:
    490
    System.Random gives much different results than UnityEngine.Random.

    Doing this nearly always uses the same 'seed' in System.Random
    Code (CSharp):
    1.         while (spawnedPeople.Count < 10)
    2.         {
    3.             System.Random randomPrefabIndex = new System.Random();
    4.             System.Random randomXCoordinate = new System.Random();
    5.             System.Random randomZCoordinate = new System.Random();
    Instead you probably want this
    Code (CSharp):
    1.      
    2.             System.Random randomPrefabIndex = new System.Random();
    3.             System.Random randomXCoordinate = new System.Random();
    4.             System.Random randomZCoordinate = new System.Random();
    5.  
    6.             while (spawnedPeople.Count < 10)
    7.             {
    8.