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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Random Range Crash

Discussion in 'Scripting' started by El3et, Aug 12, 2015.

  1. El3et

    El3et

    Joined:
    Jan 19, 2011
    Posts:
    97
    Hi everyone.

    I have to say im stumped with this one.

    When using Random.range I get a crash. No errors just a straight spiny wheel of death crash.

    When using this in code it is fine:

    Code (csharp):
    1. rand = Random.Range(0, 29);
    but when using this I get the crash. note that randomRange is an int set to 29:

    Code (csharp):
    1. rand = Random.Range(0, randomRange);

    I imagine its going to be something silly but I cant work it out. Maybe someone else can see something.

    Thanks
     
  2. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Random.Range works differently as an int than it does as a float, so if the randomRange variable is a float, even if it's assigned an int value, it'll change the actual function being called. This is dangerous being Random.Range(int, int) doesn't include the "max" number itself, just "up to max" (exclusive), while Random.Range(float, float) (and int/float and float/int by implicit conversion) will include the final number as a max value (inclusive). As it is, I have no way of knowing if you're using "var" (in Javascript or C#) and implying the value types, but that could be messing you up.

    Alternatively, randomRange isn't the value that you think it is, or you're using the nullable version "int?". Try Debug.Logging it just before this statement and make sure. Really can't be more detailed without seeing more of the script- a single line implies that you know exactly what the error is, and if you knew that, you probably wouldn't be asking for help ^_^.
     
    El3et and Not_Sure like this.
  3. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,541
    Pretty much.

    You can always call a random range, then round the output.
     
    El3et likes this.
  4. El3et

    El3et

    Joined:
    Jan 19, 2011
    Posts:
    97
    Hi Lysander & Not_Sure, thanks for the response.

    Random range is printing in the console what i expect it to so i think thats correct.

    Random range is set to an Int. And rand is also an int. So i assume I fit into your (int/int) scenario.

    What i dont understand is why when i type into the code "29" it works but doesnt work if the 29 is stored in an int variable.
     
  5. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    I've done what I could with what I had- if you want additional assistance you'll really need to post the rest of the script. As Random.Range is built into Unity and running fine for everyone else, it can't possibly be the problem here.
     
  6. El3et

    El3et

    Joined:
    Jan 19, 2011
    Posts:
    97
    Script - CBLevelManager
    Code (csharp):
    1.  
    2. xmlLoader.randomRange = 29;
    3.  
    Script - XmlLoader
    Code (csharp):
    1.  
    2. voidrandomQuestionSelection(intguiId)
    3.  {
    4.  
    5. int rand;
    6. List<int> usedNums = newList<int>();
    7. for (inti = 0; i < 11; i++)
    8.  {
    9.  
    10. rand = Random.Range(0, randomRange);
    11. Debug.Log("Agree Disagree");
    12. if(usedNums.Contains(rand))
    13.  {
    14. i--;
    15.  }
    16. else
    17.  {
    18. usedNums.Add(rand);
    19. //agreeDisagree.selectedQuestions.Add(questions[rand]);
    20. switch (guiId)
    21.  {
    22. case1:
    23. Debug.Log("Agree Disagree");
    24. agreeDisagree.selectedQuestions.Add(questions[rand]);
    25. break;
    26. case2:
    27. Debug.Log("");
    28. break;
    29.  }
    30.  }
    31.  }
    32.  }
    33.  
    I hope this helps.
     
  7. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Code (csharp):
    1. if (usedNums.Contains(rand))
    2. {
    3.    i--;
    4. }
    This is not a good way of creating a random sequence, since you could easily waste thousands of iterations. I actually wrote one the other day for somebody though, let me go see if I can find it.

    EDIT: Found it.
    Code (csharp):
    1. using System.Linq;
    2.  
    3. public List<int> RandomRangeList(int start, int count)
    4. {
    5.    List<int> randomList = new List();
    6.    List<int> remaining = Enumerable.Range(start, count).ToList();
    7.  
    8.    while(remaining.Count > 0)
    9.    {
    10.       int randomIndex = Random.Range(0, remaining.Count);
    11.       randomList.Add(remaining[randomIndex]);
    12.       remaining.RemoveAt(randomIndex);
    13.    }
    14.  
    15.    return randomList;
    16. }
     
    Last edited: Aug 12, 2015
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    As in a freeze? This normally indicates an infinite loop of some sort.

    Messing with the iterator inside of a for loop is a good way to do that. Your i-- is adding one more iteration to the loop each time it runs. Never modify i inside a for loop.

    If the code ever runs with randomRange set to a value of less then 11, you get an infinite loop.

    There are much more efficient ways to generate random orders, @Lysander posted a good one
     
  9. El3et

    El3et

    Joined:
    Jan 19, 2011
    Posts:
    97
    Hi everyone,

    Thanks for the advice last week. And thank you @Lysander your code worked brilliantly. I went back over the whole code design to make sure the approach was correct and implemented your random range code and it works better than ever.

    Thank you.