Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Unity.Mathematics.Random ALWAYS returning zero

Discussion in 'Entity Component System' started by JamesWjRose, Jan 3, 2020.

  1. JamesWjRose

    JamesWjRose

    Joined:
    Apr 13, 2017
    Posts:
    670
    So I have a job where I need to get one of a small collection or road/connection paths. There are between 2 and 8 possible connections. A small number, right. So I have the following code in Job's Execute:

    Code (CSharp):
    1.    
    2. Unity.Mathematics.Random mathRandom = new Unity.Mathematics.Random(randomSeed);
    3. int randomValue = mathRandom.NextInt(0, availableConnections.Length);
    4.  
    The "randomSeed" is created at each frame from the Time's millisecond, so this value is often different, though not ALWAYS (hey, there are only 1000 options to choose from)

    Anyway, the variable "randomValue" ALWAYS equals zero. If I change availableConnections.Length from 3 to 300, then I get different values. But when the value is 2, 3, or 4.... I only get zero chosen.

    Anyone have any thoughts?
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    You can write a simple unit test that just use the Mathematics.Random (seed with 0~999 random number, then .nextint with 2 3 4) and then compare why in your code turns out different from the test.
     
  3. Singtaa

    Singtaa

    Joined:
    Dec 14, 2010
    Posts:
    485
    Code (CSharp):
    1. Unity.Mathematics.Random mathRandom = new Unity.Mathematics.Random(1337);
    2. for (int i = 0; i < 100; i++) {
    3.     Debug.Log(mathRandom.NextInt(0, 4));
    4. }
    Produces random ints between 0 and 3 (inclusive) for me.
     
    JamesWjRose likes this.
  4. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    This test also pass, showing that I could get all values equally :

    Code (CSharp):
    1. [Test]
    2. public void RandomTest([NUnit.Framework.Range(2, 10)] int v)
    3. {
    4.     uint seed = (uint) (UnityEngine.Random.value * 10000);
    5.     Unity.Mathematics.Random mathRandom = new Unity.Mathematics.Random(seed);
    6.     int zeroCount = 0;
    7.     int nonZeroCount = 0;
    8.     for (int i = 0; i < 1000; i++)
    9.     {
    10.         int randomValue = mathRandom.NextInt(0, v);
    11.         if (randomValue == 0)
    12.         {
    13.             zeroCount++;
    14.         }
    15.         else
    16.         {
    17.             nonZeroCount++;
    18.         }
    19.     }
    20.  
    21.     float ratio = zeroCount / 1000f;
    22.     //Debug.Log($"{seed} {v} -> {zeroCount} {nonZeroCount} Ratio : {ratio}");
    23.     Assert.That(zeroCount, Is.GreaterThan(1));
    24.     Assert.That(nonZeroCount, Is.Not.Zero);
    25.     Assert.That(ratio, Is.EqualTo(1f / v).Within(0.05f), "Random is uniformly distributed.");
    26. }
    27.  
     
    JamesWjRose likes this.
  5. JamesWjRose

    JamesWjRose

    Joined:
    Apr 13, 2017
    Posts:
    670
    I SEEM to have found the issue. Because I was using the current time's millisecond, I only got seed values between 0 and 1000. When I use System.Random to create a seed that is between 0 and 100,000 I then get random values for the range I want. Seems odd, but then my understanding of Unity's Random design or abilities.
     
    Krooq and JonasMumm like this.
  6. Rud156

    Rud156

    Joined:
    Dec 25, 2017
    Posts:
    3
    I too faced the same problem. Not really sure why the seed range will affect the output of values. Can anyone give some explanation? I'm surely missing something.
     
  7. Drezta

    Drezta

    Joined:
    Nov 4, 2012
    Posts:
    8
    As far as I understand random number generation follows a (complex) pattern, the bigger the seed range the more entropy the pattern has to work with.
     
    JamesWjRose likes this.
  8. JamesWjRose

    JamesWjRose

    Joined:
    Apr 13, 2017
    Posts:
    670
    Ok, thank you kindly for the details.
     
  9. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    825
    I once had the same issue, it was because some other code that I wrote 15 months ago was writing the seed to 0 every frame to ensure it's own deterministicality and it would never set the seed value back to what it was before it ran, thus anything that ran after it, would also be deterministic. In case someone run into the same issue but it was not what OP's detected as his own issue
     
    JamesWjRose likes this.
  10. DevViktoria

    DevViktoria

    Joined:
    Apr 6, 2021
    Posts:
    94
    I have a similar problem. If I call NextInt after I had generated a new Random I constantly getting 0-s for the first time. I should call NextInt for the second time to get a non zero value. Here is the code that it is an OnUpdate of a system:
    Code (CSharp):
    1. uint seed = System.Convert.ToUInt32(Time.ElapsedTime * 10);
    2. seed = seed == 0 ? 1 : seed;
    3. Random random = new Random(seed);
    4. int index = random.NextInt(7);
    5. int index2 = random.NextInt(7);
    6.  
    7. UnityEngine.Debug.Log($"Seed: {seed}; index: {index}; index2: {index2}");
    index is constantly zero, index2 is not constantly zero.
     
  11. Krooq

    Krooq

    Joined:
    Jan 30, 2013
    Posts:
    180
    This sounds like the ol' autocast of float to int issue. Gets me every time.
     
    DevViktoria likes this.