• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by srikaran_p · Sep 23, 2016 at 11:45 AM · c#generator

How to generate a random number which is different from the last

As the title suggests, what I want is, how to generate a random number which is not equal to the previously generated number. For example, if Unity generates a number say 5, then the next number shouldn't be 5 but something else say 6 but the number after 6 can be 5 so I didn't use Lists. Is there an efficient method to do this? I know there are some resources on the Internet but they didn't give proper answers.
Thank you and any help will be appreciated.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
8
Best Answer

Answer by Namey5 · Sep 23, 2016 at 11:59 AM

 private int lastNumber;
 
 int GetRandom (int min, int max)
 {
     int rand = Random.Range (min, max);
     while (rand == lastNumber)
         rand = Random.Range (min, max);
     lastNumber = rand;
     return rand;
 }

Something like that should do it, just call this function where you would normally call Random.Range.

Comment
Add comment · Show 17 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CBRZY · Sep 23, 2016 at 12:18 PM 1
Share

This would work perfectly. You just need to make sure that lastNumber has a value to start with. I would recommend giving it a value that is outside of the range of random numbers to choose from. So if min = 0 and max = 10. Initialise lastNumber to -1 then this will work every time.

avatar image srikaran_p · Sep 23, 2016 at 12:19 PM 0
Share

Thank you very much, it worked perfectly and it cut down a lot of lines of code of mine.

avatar image srikaran_p · Sep 23, 2016 at 12:22 PM 0
Share

@$$anonymous$$rBrits sir, I didn't make any changes to my lastNumber variable. It is just outside the range. But what happens if my lastNumber is within the range?

avatar image PlayCreatively srikaran_p · Sep 23, 2016 at 12:39 PM 2
Share

Pretty much means that the GetRandom function might need to make multiple Random.Range numbers because the lastNumber was equal to the number that Random.Range made. This is just for efficiency.

avatar image Bonfire-Boy srikaran_p · Sep 23, 2016 at 05:06 PM 1
Share

If lastNumber is initialised to a number within the range, it would have a small effect on your distribution (the first random number picked can't ever be that particular number) and a tiny effect on your speed (that first number might take a tiny amount more time to get picked).

avatar image elenzil · Sep 23, 2016 at 11:06 PM 1
Share

i'd suggest checking that max > min + 1. Random.Range(A, B) will return at most B -1, so if B == A or B == A + 1, this will be an infinite loop.

avatar image Bonfire-Boy elenzil · Sep 23, 2016 at 11:58 PM 0
Share

Fair point. If max == min+1 it should either a) return min because that's the only possible value (Namey5's function assumes that the OP wants an exclusive max value) OR b) throw an exception (because it's not possible to return a random number different to the last one, so the function's implicit contract is not met).

But if you're needing to check for this then you maybe you shouldn't be calling it in the first place. If I thought there was a chance this might be called with inappropriate values then I would also check for max <= min and throw an exception then too.

avatar image Namey5 elenzil · Sep 24, 2016 at 06:09 AM 0
Share

Indeed. How I personally would do it is just inverse the variables, i.e.

 private int lastNumber;
          
 int GetRandom (int min, int max)
 {
     int l = min;
     int g = max;
     if (min > max || max < min)
     {
         l = max;
         g = min;
     }
     if (lastNumber == null)
         lastNumber = l - 1;
     int rand = Random.Range (l, g);
     while (rand == lastNumber)
         rand = Random.Range (l, g);
     lastNumber = rand;
     return rand;
 }
avatar image elenzil Namey5 · Sep 24, 2016 at 06:53 AM 2
Share

hm. a couple things -

  • there's no need to check that min < max. that's already a constraint imposed by Random.Range().

  • if you insist on checking that min < max, fwiw, "min > max" is equivalent to "max < min".

  • re "lastNumber == null", int's cannot be null.

  • you want to move "lastNumber = rand" inside the while() loop.

here's what i'd suggest:

 static int GetRandom(int min, int max, int butNotThis) {
     int maxIters = 20;
     for (int n = 0; n < maxIters; ++n) {
         int val = Random.Range(min, max);
         if (val != butNotThis) {
             return val;
         }
     }
     return butNotThis;
 }


if this is going to be called frequently and performance is an issue, it would probably make sense to pre-generate a list of all the possible return values, and when getRand() is called choose a random entry between index 1 (not 0) and the end, and then swap that entry with index 0. that would be a big-O of O(1). hm, i'm not sure what the big-O of the unbounded while() approaches would be. i think they might be O(infinity). like it's O(1) + O(1/n) + O(1/n) + .... forever.

Show more comments
Show more comments
avatar image ZombiesCam · Jul 30, 2020 at 08:37 PM 0
Share

No witty comment here, just that this is amazing. Something I can't seem to wrap my head around for the life of me

avatar image
1

Answer by amiel_ace · Sep 23, 2016 at 12:12 PM

 prevNum = newNum;
 
 newNum = Random.value * range;
 if (newNum == prevNum)
      newNum = Random.value * range;
     
  //use newNum here
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image srikaran_p · Sep 23, 2016 at 12:18 PM 0
Share

Thank you very much for taking your time to answer my question.

avatar image Bonfire-Boy · Sep 23, 2016 at 11:39 PM 1
Share

This is wrong. It doesn't work because the new value of newNum could also be equal to prevNum. Namey5 is correct to use while ins$$anonymous$$d of if.

avatar image
0

Answer by ayhaab-pasha · Oct 24, 2018 at 07:19 AM

Maybe this would be helpful for someone. I was trying to spawn enemy planes in Augmented Reality. I wanted them to be randomly spawned but at a distance. For example, if one plane is spawned at 0,0,0. I wanted the next plane to be spawned at 0+20 or 0-20 on the X-Axis. Like, the new plane should spawn at 20 or more points from the present spawned point in positive and negative direction. Using @Namey5 solution, i came to this:

     void RandonDistanceAxis()
     {
         distanceX = Random.Range (-70, 70);
         while (distanceX <= tempx + 20 && distanceX >= tempx - 20 )
         {
             distanceX = Random.Range (-70, 70);
         }
         tempx = distanceX;

         distanceY = Random.Range (-10,10);
         distanceZ = Random.Range (60,90);
     }

While declaring the tempx variable, give it a value of something out of the Range. I used 71. And it worked perfectly fine.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

228 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Generate floor mesh according to walls 0 Answers

Initialising List array for use in a custom Editor 1 Answer

My T4 template tt file customtool changes when editor updates assets 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges