UnityEngine.Random和System.Random有什么区别?


24

这有什么不同

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

和这个

// 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);

我知道System.Random必须始终在类的顶部进行初始化,UnityEngine.Random不需要使用什么。我也知道这System.Random适用于实习生“时钟”,“随机”数字是基于此的。

我的问题是,现在UnityEngine.RandomSystem.Randomand 之间还有其他区别,并且更适合在Unity项目中使用巫婆代码?

Answers:


23

可以说,最重要的区别是Unity的Random.Range静态性更易于使用。System.Random但是,C#基类库为您提供了更多控制和隔离。

他们也有可能使用不同的幕后实现(尽管我猜测是Unity Random是根据系统实现的Random),但这并不是一个值得注意的问题。从根本上说,它们都可能是同一类型的随机数生成器:基于迭代某个种子定义的序列的伪随机生成器。

控制问题更为相关,因为在某些情况下,您可能希望对不同的事物使用不同的随机流。例如,在锁定步骤网络环境中,您可能希望修复用于在游戏中所有玩家之间生成影响游戏随机事件的种子,但您可能不太在乎纯粹用于生成随机数流的情况。视觉事件,并可以使该流以更传统的方式播种(例如,在游戏启动时具有系统正常运行时间)。

同样,如果要在多个线程中生成随机数,则可能需要为每个线程使用不同的随机对象,以防止出现竞争情况。例如,如果您的游戏逻辑跨多个线程运行,并且您还具有一个游戏重播系统,则可能会出现这种情况。

最后,一般来说,使用一种或另一种不一定更好,但有其优缺点。当您需要将数字序列与可能发生的其他潜在随机序列隔离开来时,或者需要对序列的种子进行局部控制时,请使用的实例System.Random。如果您只需要一个快速脏乱的随机值以用于一次性使用或其他非干扰性场景,则Unity的简化Random可能就可以了。


3
一些游戏所做的一件事是在玩家保存游戏时保存种子值。这样,相同的动作会导致相同的结果。它不鼓励保存垃圾,如果您以后忘记保存,则可以返回以前的状态。最后一个XCOM做到了。
GregRos

3
@GregRos请注意,但是它可以引入本文所述的另一种节省储蓄的方法 -基本上,与其尝试重试相同的动作直到成功,它还是尝试了不同的动作序列,直到他们关心的是大多数着陆为止按预定顺序成功滚动。事实证明,在所有具有保存功能的系统中,都存在保存暨的方法。Scummers Scummers,所以有时候像XCOM一样顺其自然
DMGregory

10

UnityEngine.Random具有一些易用性优点:

  • 静态/全局访问-无需为每个需要随机性的对象或系统创建实例。您的大多数或所有脚本都可以共享此资源。

  • 便捷方法-您可以使用Random.Range(),Random.insideUnitSphere,Random.rotationUniform,Random.ColorHSV()来获得各种有用类型的分布良好的随机值,而无需自己动手算术。

(我还没有发现关于UnityEngine.Random是否提供任何跨平台一致性保证的确认(不同于System.Random的Mono实现的确认-它们在内部可能相同,也可能不同))

您当然可以构建自己的使用System.Random的类(或其他库,或您自己的PRNG)来执行此操作,但是最重要的是您不需要-Unity的实现旨在为您提供良好的基线开箱即用的随机行为。

也就是说,在某些情况下,您可能希望使用其他随机性来源:

  • 如果您使用多个线程,则每个线程应具有其自己的伪随机源,以避免争用(UnityEngine.Random仅可在主线程上访问)

  • 如果您需要确定性的伪随机序列(例如,用于种子级生成器),则可能希望该系统拥有自己的伪随机源,其他脚本无法访问该伪随机源,以便执行顺序上的差异不会导致它跳过数字并破坏您所依靠的确定性。有关更多信息,Unity博客上一篇很棒的文章,介绍了种子随机数

  • 如果您出于安全性,赌博或生成唯一ID的需要,需要使用密码学上很强的随机性,则应为此使用专门的库。UnityEngine.Random和System.Random都不提供足够的质量保证。


抱歉,为JoshPetrie和Jon道歉-我花了一段时间在手机上输入,所以直到将其发布后,我才看到您的答案。看起来我们都涵盖了相似的领域。
DMGregory

有关加密级的随机性,请参见RNGCryptoServiceProvider,但请记住,它非常慢,并且已被Unity的所有剥离式.NET平台所排除。
McGuireV16年

6

UnityEngine.Random是静态的。如果要创建随机数生成器的多个实例,则需要使用System.Random。

无法查找Unity实施的源代码,但是Microsoft提供了System.Random的源。


3
并不是说Microsoft的来源不是Unity使用的来源。您应该改为查看Mono来源。
Arturo TorresSánchez16年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.