Search Unity

Problems with Random Numbers?

Discussion in 'iOS and tvOS' started by BigRedSwitch, Apr 14, 2009.

  1. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    723
    Hey, All,

    I'm having some issues with random numbers in Unity iPhone.

    I want my App to play a random sound when it's started, so I've put this line in my Audio Object script:

    SoundChoice = Mathf.Round((Random.value*19)+1);

    This should give me a number between 1 and 20.

    It works fine in the editor - every time I start the app, a different sound starts, but the problem is that when I upload it to my iPhone, the app seems to "Choose" a random number and then just uses that number every time the app is used until I re-install the app.

    That ain't cool!

    I'm pretty sure I'm doing everything right (hey, it all works A-OK in the editor!), so is there a gotcha I'm missing which would mean it wouldn't work on the device?

    Thanks, in advance for any info! :)

    SB
     
  2. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    723
    Oh yeah - and then there are other times when no audio plays at all! Totally random too! This seems to be VERY flaky! :(
     
  3. G-o-D933

    G-o-D933

    Joined:
    Oct 15, 2008
    Posts:
    185
    hm, never noticed that, although i use Random.Range() - maybe it works better.

    but anyway, if this happens, you have to change the seed (Random.seed) - on other systems, you usually take the system timestamp, but i don't know how to get it in unity. maybe saving a random number in preferences and use that random number as seed on next startup might help.
     
  4. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    Random.Range() works perfectly for me . Surprisingly well actually considering I am not even setting the seed value!

    edit:
    whoops I was wrong. I am getting roughly the same initial values on the device. Need to seed. This is just how pseudo-random number generators work.
     
  5. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    The accelerometer is the best random # generator I can think of on the iphone.

    // call this during gameplay, before you call Random.* functions
    Random.seed = iPhoneInput.acceleration.x * MAX_INT;

    // MAX_INT = 32767 ? not sure but this value seems to work
    //edit: nope just use someInt.MaxValue like Random.seed.MaxValue
     
  6. Poita_

    Poita_

    Joined:
    Dec 18, 2008
    Posts:
    146
    Wait, what's this... Random.Range() doesn't automatically choose a random seed on the device, but it does in the editor?
     
  7. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    I'm not sure the seed is chosen automatically by that function. But Random numbers seem to be better in the editor for some reason. Maybe it's because the game engine is being loaded and scripts have run, even before you run your level in the editor. I know that in 2.5 the whole UI is written in Unityscript. Just guessing this has something to do with it in Unity iPhone as well.

    I was thinking about the accelerometer and it's kind of like having a built-in entropy generator :)
     
  8. jdm

    jdm

    Joined:
    Jan 3, 2009
    Posts:
    86
    this *should* work for seeding based on current time on the iphone (haven't tested it on actual hardware yet)

    Random.seed = System.DateTime.Now.Ticks;

    should seed with the number of 100-nanosecond ticks that have elapsed from some date - either jan 1 1970 or jan 1 0001...

    I actually like that the RNG isn't seeded for us - makes testing some things a bit easier - and also allows you to seed with 'known' seeds to get repeatable psuedo-random behaviour, if you want it.

    -jdm
     
  9. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    jdm, Ticks is an int64 and I get an overflow exception when assigning it to the int32 Random.seed. This seems to work though in Unity javascript:
    Code (csharp):
    1. var ticks : String =  System.DateTime.Now.Ticks.ToString();
    2. Random.seed = parseInt( ticks.Substring( ticks.length - 8, 8 ));
     
  10. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    Maybe use both!
    Code (csharp):
    1. function initRandomSeed ()
    2. {
    3.     if( iPhoneInput.acceleration.x )
    4.     {
    5.         Random.seed = iPhoneInput.acceleration.x * Random.seed.MaxValue;
    6.     }
    7.     else
    8.     {
    9.         var ticks : String =  System.DateTime.Now.Ticks.ToString();
    10.         Random.seed = parseInt( ticks.Substring( ticks.length - 8, 8 ));
    11.     }
    12. }
     
  11. Poita_

    Poita_

    Joined:
    Dec 18, 2008
    Posts:
    146
    Why not just cast the int64 to an int32?
     
  12. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    How do you cast in Unity javascript... ?

    [edit: also it might simply be to large for int32, right?]
     
  13. Poita_

    Poita_

    Joined:
    Dec 18, 2008
    Posts:
    146
    Hmm, now that you mention it, I don't think you can.

    Use C# ;)

    I believe if it's too big then it will just take the lower 32 bits, although I haven't tested this. That makes the most sense to me though.
     
  14. Wozik

    Wozik

    Joined:
    Apr 10, 2009
    Posts:
    662
    Look for 1.0.2 release next week. Those issues will be gone ;-)
     
  15. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,670
    I am assuming if I read this correctly, that one still needs to seed the random number, but the "no sound" at start was the issue fixed with 1.0.2.

    Am I correct?
     
  16. Wozik

    Wozik

    Joined:
    Apr 10, 2009
    Posts:
    662
    I didn't have a chance to play with random numbers yet, but have this task in my tasklist. It's always better to bugreport if you want a bugfix or more or less official statement about bug. And bugreports have higher priority then forum things now.

    And yes, most sound bugs are fixed in 1.0.2.
     
  17. mindlube

    mindlube

    Joined:
    Oct 3, 2008
    Posts:
    993
    Random works fine- I think there was just a question about seeding. What I found is in the editor maybe it is seeding automatically but on the device it's not?
     
  18. BigRedSwitch

    BigRedSwitch

    Joined:
    Feb 11, 2009
    Posts:
    723
    I can confirm the sound bugs are all sorted in 1.0.2. As for the random numbers - I moved to "RANGE" and everything has been cool since. :)
     
  19. christopherbrown

    christopherbrown

    Joined:
    Oct 19, 2009
    Posts:
    83
    Lots of good discussion and ideas here...

    The questions I have are these:
    • How does Random.Range get seeded?
    • Does Random.Range seed itself before each call?
    • Will assigning Random.seed improve my "randomness" on the iOS device? If so, where is the optimal place to seed (Start, before a Random.Range call)?

    I've been told in the past to trust the automagic nature of Unity's RNG, but I refuse.
     
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,175
    No. The only reason to use Random.seed is if you want a repeatable set of "random" numbers; otherwise don't touch it. Not sure how it's seeded internally; probably time/date or something, but regardless, if you just want ordinary random numbers, the randomness is fine as-is.

    --Eric
     
  21. christopherbrown

    christopherbrown

    Joined:
    Oct 19, 2009
    Posts:
    83
    Very good. Thanks.