25
\$\begingroup\$

What's the different between this

int randomNumber = UnityEngine.Random.Range(0, 10);

and this

// on top of the class
private System.Random _rnd = new System.Random();

// inside a methode of the same class
int randomNumber = _rnd.Next(0, 10);

I know System.Random must always be initialized on the top of your class what's by UnityEngine.Random is not needed. I know also that System.Random works with a intern "clock" and the "random" number is based on that.

My question is now are there some other difference between UnityEngine.Random and System.Random and witch code is better to use for an Unity project?

\$\endgroup\$
1

3 Answers 3

24
\$\begingroup\$

Arguably the most important difference is that Unity's Random.Range is slightly easier to use, being static. The C# base class library System.Random, however, offers you more control and isolation.

It's possible they also use different under-the-hood implementations (although my guess would be that Unity's Random is just implemented in terms of the system Random), but that's probably not a notable concern. Fundamentally they're both likely the same kind of random number generator: a pseudo-random generator based on iterating a sequence defined by some seed).

The control issue is more relevant, because in some contexts you may want to use different random streams for different things. For example, in a lock-step networking networking context, you may want to fix the seed used to generate random gameplay-affecting events across all players in the game, but you may not care so much about the stream of random numbers used for purely visual events and can allow that stream to be seeded in a more traditional fashion (with the system uptime at game launch, for example).

Similarly, if you are going to be generating random numbers in multiple threads you may want to use distinct random objects for each thread in order to prevent race conditions. This may come up if your game logic runs across many threads and you also have a gameplay replay system, for example.

In the end, it's not necessarily better to use one or the other in general, rather there are pros and cons. When you need to isolate the sequence of numbers from other potential random sequences that may be happening, or when you need localized control over the seed of the sequence, use an instance of System.Random. If you just need a quick-and-dirty random value for a throw-away use or some other non-impactful scenario, Unity's simplified Random is probably fine.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ One thing some games do, is save the seed value when the player saves the game. That way, the same actions lead to the same consequences. It discourages save scumming, and if you forgot to save at a later point, you can just return to where you were before. The last XCOM did that. \$\endgroup\$
    – GregRos
    Jan 4, 2016 at 19:39
  • 3
    \$\begingroup\$ @GregRos Good note, but it can introduce a different kind of save-scumming as described in this article - basically instead of retrying the same move until they roll a success, the player tries different sequences of moves until the moves they care about most land on successful rolls in the pre-determined sequence. It turns out there's ways to savescum in any system with saves. Scummers Gonna Scum, so sometimes it makes sense to go with the flow as XCOM did. \$\endgroup\$
    – DMGregory
    Jan 4, 2016 at 20:17
11
\$\begingroup\$

UnityEngine.Random has a few ease of use advantages:

  • Static/globally accessible — you don't need to create an instance for each object or system that needs randomness. Most or all of your scripts can share this resource.

  • Convenience methods — you can use Random.Range(), Random.insideUnitSphere, Random.rotationUniform, Random.ColorHSV() to get nicely-distributed random values of various useful types without needing to roll your own math.

(I have not found any confirmation about whether UnityEngine.Random provides any cross-platform consistency guarantees different from the Mono implementation of System.Random - they might or might not be the same under the hood)

You can of course build your own class that uses System.Random (or another library, or your own PRNG) to do this, but the nice part is you don't need to — Unity's implementation is meant to give you a good baseline for random behaviour out of the box.

That said, there are cases where you'll want to use other sources of randomness:

  • If you're using multiple threads, each thread should have its own source of pseudorandomness to avoid contention (UnityEngine.Random is only accessible on the main thread)

  • If you need a deterministic pseudorandom sequence (eg. for a seeded level generator) you'll probably want that system to have its own source of pseudorandomness that no other script can access, so that differences in order of execution don't cause it to skip numbers and break the determinism you were counting on. For more info, there's a great post on the Unity blog about seeded random numbers.

  • if you need cryptographically strong randomness for security, gambling, or generating unique IDs, you should use specialized libraries for this purpose. Neither UnityEngine.Random nor System.Random provide sufficient quality guarantees.

\$\endgroup\$
1
  • \$\begingroup\$ For crypto-grade randomness see RNGCryptoServiceProvider but bear in mind that it is very slow and that it is excluded from all of Unity's stripped .NET platforms. \$\endgroup\$
    – McGuireV10
    Jun 30, 2016 at 13:40
6
\$\begingroup\$

UnityEngine.Random is static. If you wanted to create multiple instances of a random number generator, then you would want to use System.Random.

There is no way to look up the source code for the Unity Implementation, however, Microsoft provides the source for System.Random.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Not that Microsoft's source is not the one used by Unity. You should look at the Mono source instead. \$\endgroup\$ Jan 5, 2016 at 1:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .