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 number only once

Discussion in 'Scripting' started by DLGScript, Aug 6, 2016.

  1. DLGScript

    DLGScript

    Joined:
    Jul 15, 2012
    Posts:
    272
    Hey guys it's me again :)
    I got this code:
    if (score >= 100)
    If the score is bigget\equal 100, then....
    But i want to make it be less Fixed.. that not all the time the the score will be bigger or equal to 100 something will be happen.
    I want the the score will be randomalic between 90 to 110.
    So I read about the function "Random".
    and I tried to use it without success.
    The problem is that I'm coding it in my Update function, and when i'm using the random code and not choosing a random number between 90 to 110 only oce, because it's in the update function its generating the random number NON-STOP.

    So my question is: how can i save the random number in a int var that will not get changed, how can i get a random number only once when i'm using the Update function :)??
    Thanks in advance:)
     
  2. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Why can't you just set the random number in the Awake or Start methods?
     
  3. DLGScript

    DLGScript

    Joined:
    Jul 15, 2012
    Posts:
    272
    Because the int variable that saves the random number need to change while playing the game.
    There are few more "if" 's that i want to random the score of them.
     
  4. RavenOfCode

    RavenOfCode

    Joined:
    Apr 5, 2015
    Posts:
    869
    Just make another int, call it like scoreRandom and set it in Start().
     
  5. DLGScript

    DLGScript

    Joined:
    Jul 15, 2012
    Posts:
    272
    but there must be another way to use only 1 variable..
     
  6. GNGification

    GNGification

    Joined:
    Oct 24, 2013
    Posts:
    59
    Messy post coming, written on phone.

    You could use a bool and set it to true when you want to generate a new number and set it false right after that.

    Or you could call it from the script that gives you points if you reset them after it.

    - On start create first value with random.range
    - As soon score >= Value,change value again and set score to 0 etc.

    If you dont want to set the score to 0, do the same using a bool or somehing like that.

    Just giving some ideas... someone probably already wrote a better answer while I was writing this.

    Edit, also written on phone
    Code (csharp):
    1.  
    2. int Value;
    3. void Start(){
    4.        Value = RandomValue(90,110)
    5. }
    6.  
    7. void Update(){
    8.      if(Score >= Value){
    9.               //DoSomething
    10.               Score = 0;
    11.              //or increase value
    12.              //or use bool
    13.       }
    14. }
    15.  
    16. int RandomValue(int x, int y){
    17.         int temp = Random.Range(x,y);
    18.         return temp;
    19. }
    20.  
     
    Last edited: Aug 6, 2016
  7. RavenOfCode

    RavenOfCode

    Joined:
    Apr 5, 2015
    Posts:
    869
    Why do u only want to use one?
     
  8. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    A better question is, what are you trying to do? When do you want to switch random numbers? Because if all you want to do is make a check and then generate a new random number, you should just have a method that creates a new random after the check. I'm not sure how often you want to do that check.
     
  9. btmedia14

    btmedia14

    Joined:
    May 27, 2016
    Posts:
    3
    Code (CSharp):
    1.     private int _threshold;
    2.     public int Threshold
    3.     {
    4.         get
    5.         {
    6.             if (_threshold == 0)
    7.                 _threshold = Random.Range(90, 110);
    8.             return _threshold;
    9.         }
    10.  
    11.     }
    12.  
    13.     void Update()
    14.     {
    15.         if (Score >= Threshold)
    16.         {
    17.             //DoSomething
    18.         }
    19.     }
    Reset Threshold value as needed either by adding setter, or updating private variable.
     
  10. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    @btmedia14
    That's so cryptic, why not just the following?
    Code (CSharp):
    1. private int _threshold;
    2.  
    3. void RandomizeThreshold()
    4. {
    5.     _threshold = Random.Range(90, 110);
    6. }
    7.  
    8. void Start()
    9. {
    10.     RandomizeThreshold();
    11. }
    12.  
    13. void Update()
    14. {
    15.     if (Score >= _threshold)
    16.     {
    17.         //DoSomething
    18.     }
    19. }
    20.  
     
  11. btmedia14

    btmedia14

    Joined:
    May 27, 2016
    Posts:
    3
    @ericbegue
    Sure, that's fine too. Also, use of functions with a return value as someone mentioned earlier. The sample was demonstrating use of a Property to encapsulate and hide randomization with getter and setter to control access. This comes more into play when used beyond the containing class. But if random is only needed within this one class, then sure that example is good also.
     
    RavenOfCode likes this.
  12. RavenOfCode

    RavenOfCode

    Joined:
    Apr 5, 2015
    Posts:
    869
    @ericbegue Just curious but why is @btmedia14 's version cryptic? To me his seems just as good if not better, less methods are good right?
     
  13. btmedia14

    btmedia14

    Joined:
    May 27, 2016
    Posts:
    3
    Actually @ericbegue makes a good point. Code should be simple and straightforward for future maintenance. If not, we have made a disservice to others. Didn't mean to add complexity.
    Also: "less methods are good, right?" The number of methods shouldn't factor into how code is defined, its more about design. Anyway, even in the Property version, the getter and setters actually get turned into function calls by the compiler!
     
    ericbegue and RavenOfCode like this.
  14. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Another way to do this would be to use a FSM or BT. Both are a little more complex, and require more boilerplate. But they do handle sequential logic better then simple Update.
     
    RavenOfCode likes this.
  15. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Don't get me wrong, properties are great tool to do encapsulation. But what I don't like is that calling Threshold does more that returning the threshold: it will randomise it if the current threshold value is zero. That is the getter does more than its name suggests, that could be misleading. Furthermore, you would need to set the threshold to zero to obtain a new randomise threshold, which seems to come out of no where, as well as it breaks the encapsulation.

    Alright. Now you're just kidding me.:)
     
    Last edited: Aug 7, 2016
    btmedia14 and RavenOfCode like this.
  16. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    ;)

    I use simple coroutine FSMs for this sort of behaviour all the time.

    Code (CSharp):
    1. public int someValue;
    2.  
    3. void Start (){
    4.     StartCoroutine(MyMethod());
    5. }
    6.  
    7. IEnumerator MyMethod (){
    8.     int threshold = 100 + Random.Range (-20,20);
    9.     while (someValue <= threshold) yield return null;
    10.     // Do something awesome only once
    11. }
    It's probably overkill to go for a full blown state machine or behaviour tree. But these are both valid approaches if the sequence gets more complicated.
     
    ericbegue likes this.
  17. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    @BoredMormon
    Couroutines, FSM and BT are indeed ways to go for more complex logics.

    I am wondering: what do you mean by "coroutine FSMs"? Do you mean implementing FSMs using coroutines or something else?
     
  18. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    A coroutine is by definition a FSM. Which makes them great for simple sequential logic. They are not great for branching FSMs.

    Here is a more explicit example.

    Code (CSharp):
    1. IEnumerator MyFSM(){
    2.     DoStateOneEnter();
    3.     while (inStateOne){
    4.         DoStateOneLogic();
    5.         yield return null;
    6.     }
    7.     DoStateOneExit();
    8.     DoStateTwoEnter();
    9.     // and so on
    10. }
    Throw a while (true) around the whole thing and your machine will loop. Great for reloading, simple doors, ect.
     
    Trexug and RavenOfCode like this.
  19. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Hmm... I wouldn't put it in that order. I would rather say that coroutines are by definition sequences, so they are great at implementing sequential FSMs. I agree that coroutines are not great at implementing FSMs in general, excepted sequential FSMs.
     
  20. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    A finite state machine is an abstract machine that can be in a finite number of states, and can only be in one state at a time. A single coroutine fits that definition.

    One might say that coroutines are a subset of FSMs. As in all coroutines are FSMs, but not all FSMs are coroutines.
     
  21. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    @BoredMormon
    A CPU has a finite number of instructions and the memory on any real computer is finite. So, how a computer executes instructions can be modelled as an FSM. To this extend, any program at its lowest level is an FSM.

    But this is not how I am considering FSM for game development. In this context, FSM are used to model a piece of high-level logic (e.g. an AI). Once you have an FSM defined (like using pen and paper), the next step is to choose a way to implement it. Then, coroutine can be one way of implementing that FSM (only if it is a sequential one). That's how I relate coroutine to FSM.

    For clear thinking, I won't think of couroutine as some sort of FSM by nature, because that won't help me better understand the code. I rather think of them as what they are: a way to implement an enumerated sequence, and not think of them in terms of states and state transitions. So, to me, they are not FSM, but only a way to implement a sub-set of FSM (the sequential ones).
     
    Last edited: Aug 8, 2016
  22. yohannaluv339

    yohannaluv339

    Joined:
    Oct 13, 2018
    Posts:
    1
    How to make a tambola bingo random number between 1-90 calling only once....
     
  23. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    @yohannaluv339 in your case as your number range is so small, it would be easy to use a list of numbers and remove them from the list as soon as they are used.

    But in case you needed large numbers like thousands or hundreds of thousands, I would suggest you look into the topic of topic of pseudo random generators and more specifically how to generate a non-repeating sequence of int numbers.