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、インターン「クロック」で動作し、「ランダム」な数値がそれに基づいていることも知っています。

私の質問は、Unityプロジェクトに使用するのがより良いと魔女のコードの間に他の違いがUnityEngine.RandomありSystem.Randomますか?

回答:


23

おそらく最も重要な違いは、Unityの方Random.Rangeが少し使いやすく、静的であるということです。System.Randomただし、C#基本クラスライブラリは、より多くの制御と分離を提供します。

彼らは異なる内部の実装も使用する可能性があります(私の推測ではUnity Randomはシステムの観点から実装されているだけでしょうRandom)が、それはおそらく注目すべき問題ではありません。基本的に、これらは両方とも同じ種類の乱数ジェネレーターである可能性があります。つまり、シードによって定義されたシーケンスの反復に基づいた擬似乱数ジェネレーターです。

コンテキストによっては、さまざまなものに異なるランダムストリームを使用する場合があるため、制御の問題はより関連性があります。たとえば、ロックステップネットワーキングネットワーキングコンテキストでは、ゲーム内のすべてのプレーヤーでランダムなゲームプレイに影響するイベントを生成するために使用されるシードを修正することができますが、純粋に使用される乱数のストリームについてはあまり気にしない場合があります視覚的なイベントを生成し、そのストリームをより伝統的な方法でシードできるようにすることができます(たとえば、ゲームの起動時のシステムの稼働時間)。

同様に、複数のスレッドで乱数を生成する場合は、競合状態を防ぐために、スレッドごとに個別のランダムオブジェクトを使用することができます。これは、ゲームロジックが多数のスレッドで実行され、たとえばゲームプレイリプレイシステムもある場合に発生する可能性があります。

結局のところ、一般的にどちらか一方を使用するが必ずしも良いとは限らず、むしろ賛否両論があります。発生する可能性のある他の潜在的なランダムシーケンスから数値のシーケンスを分離する必要がある場合、またはシーケンスのシードを局所的に制御する必要がある場合は、のインスタンスを使用しますSystem.Random。使い捨てやその他の影響のないシナリオのために迅速で汚いランダム値が必要な場合、Unityの単純化Randomはおそらく問題ありません。


3
一部のゲームでは、プレーヤーがゲームを保存するときにシード値を保存します。そのように、同じアクションは同じ結果につながります。それは節約の詐欺を思いとどまらせます、そしてあなたが後の時点で節約することを忘れたなら、あなたはちょうどあなたが前にいたところに戻ることができます。最後のXCOMはそれをしました。
-GregRos

3
@GregRos良いメモですが、この記事で説明されているように、異なる種類のセーブスカムを導入できます -基本的に、成功するまで同じ動きを再試行する代わりに、プレイヤーはほとんどの土地を気にする動きまで異なる動きのシーケンスを試します事前に決められた順序で成功したロール。あらゆるシステムにセーブ機能を備えたセーブカムを行う方法があります。Scummers Gonna Scumので、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プラットフォームから除外されることに留意してください。
McGuireV10

6

UnityEngine.Randomは静的です。乱数ジェネレーターの複数のインスタンスを作成する場合は、System.Randomを使用します。

Unity実装のソースコードを検索する方法はありませんが、MicrosoftはSystem.Randomのソースを提供しています。


3
MicrosoftのソースがUnityによって使用されているわけではありません。代わりに、Monoソースをご覧ください。
アルトゥーロトレスサンチェス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.