Qual è la differenza tra UnityEngine.Random e System.Random?


24

Qual è la differenza tra questo

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

e questo

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

So che System.Randomdeve sempre essere inizializzato in cima alla tua classe che cosa UnityEngine.Randomnon è necessario. So anche che System.Randomfunziona con un "orologio" interno e il numero "casuale" si basa su quello.

La mia domanda è ora ci sono alcune differenze tra UnityEngine.Randome System.Randome il codice strega è meglio usare per un progetto Unity?

Risposte:


23

Probabilmente la differenza più importante è che Unity Random.Rangeè leggermente più facile da usare, essendo statico. La libreria di classi base C # System.Random, tuttavia, offre maggiore controllo e isolamento.

È possibile che utilizzino anche diverse implementazioni nascoste (anche se la mia ipotesi sarebbe che Unity Randomsia implementata solo in termini di sistema Random), ma probabilmente non è una preoccupazione notevole. Fondamentalmente sono entrambi probabilmente lo stesso tipo di generatore di numeri casuali: un generatore pseudo-casuale basato sull'iterazione di una sequenza definita da alcuni seed).

Il problema del controllo è più rilevante, perché in alcuni contesti potresti voler usare diversi flussi casuali per cose diverse. Ad esempio, in un contesto di rete in blocco, potresti voler correggere il seme utilizzato per generare eventi casuali che influenzano il gameplay tra tutti i giocatori nel gioco, ma potresti non preoccuparti così tanto del flusso di numeri casuali utilizzati esclusivamente eventi visivi e può consentire il seeding di quel flusso in modo più tradizionale (ad esempio con il tempo di attività del sistema all'avvio del gioco).

Allo stesso modo, se stai per generare numeri casuali in più thread, potresti voler utilizzare oggetti casuali distinti per ogni thread al fine di prevenire le condizioni di competizione. Questo può emergere se la tua logica di gioco attraversa molti thread e hai anche un sistema di riproduzione del gameplay, ad esempio.

Alla fine, non è necessariamente meglio usare l'uno o l'altro in generale, piuttosto ci sono pro e contro. Quando è necessario isolare la sequenza di numeri da altre potenziali sequenze casuali che potrebbero verificarsi o quando è necessario un controllo localizzato sul seme della sequenza, utilizzare un'istanza di System.Random. Se hai solo bisogno di un valore casuale rapido e sporco per un uso a eliminazione diretta o per qualche altro scenario non di impatto, Randomprobabilmente la semplificazione di Unity va bene.


3
Una cosa che alcuni giochi fanno è salvare il valore del seme quando il giocatore salva il gioco. In questo modo, le stesse azioni portano alle stesse conseguenze. Scoraggia il salvataggio della feccia, e se ti sei dimenticato di salvare in un secondo momento, puoi semplicemente tornare al punto in cui eri prima. L'ultimo XCOM l'ha fatto.
GregRos,

3
@GregRos Nota bene, ma può introdurre un diverso tipo di salvataggio-scrumming come descritto in questo articolo - fondamentalmente invece di riprovare la stessa mossa fino a quando non ottengono un successo, il giocatore prova diverse sequenze di mosse fino alle mosse che gli interessano della maggior parte della terra su tiri riusciti nella sequenza predeterminata. Si scopre che ci sono modi per salvare in qualsiasi sistema con salvataggi. Scummers Gonna Scum, quindi a volte ha senso seguire il flusso come ha fatto XCOM .
DMGregory

10

UnityEngine.Random ha alcuni vantaggi di facilità d'uso:

  • Statico / accessibile a livello globale: non è necessario creare un'istanza per ogni oggetto o sistema che richiede casualità. La maggior parte o tutti i tuoi script possono condividere questa risorsa.

  • Metodi di convenienza: è possibile utilizzare Random.Range (), Random.insideUnitSphere, Random.rotationUniform, Random.ColorHSV () per ottenere valori casuali ben distribuiti di vari tipi utili senza dover eseguire il rollio della propria matematica.

(Non ho trovato alcuna conferma sul fatto che UnityEngine.Random fornisca garanzie di coerenza multipiattaforma diverse dall'implementazione Mono di System.Random: potrebbero o meno essere le stesse sotto il cofano)

Naturalmente puoi costruire la tua classe che utilizza System.Random (o un'altra libreria o il tuo PRNG) per farlo, ma la parte bella è che non è necessario - L'implementazione di Unity è pensata per darti una buona base per comportamento casuale fuori dalla scatola.

Detto questo, ci sono casi in cui vorrai usare altre fonti di casualità:

  • Se stai usando più thread, ogni thread dovrebbe avere la sua fonte di pseudocasuale per evitare contese (UnityEngine.Random è accessibile solo sul thread principale)

  • Se hai bisogno di una sequenza pseudocasuale deterministica (ad es. Per un generatore di livelli seeded) probabilmente vorrai che quel sistema abbia la sua fonte di pseudo casualità a cui nessun altro script può accedere, in modo che le differenze nell'ordine di esecuzione non lo causino salta i numeri e spezza il determinismo su cui contavi. Per ulteriori informazioni, sul blog Unity è disponibile un post sui numeri casuali con seeding .

  • se hai bisogno di casualità crittograficamente forte per sicurezza, gioco d'azzardo o generazione di ID univoci, devi utilizzare librerie specializzate a questo scopo. Né UnityEngine.Random né System.Random forniscono sufficienti garanzie di qualità.


Spiacenti, mi scuso con JoshPetrie e Jon: ho impiegato un po 'a scrivere questo sul cellulare, quindi non ho visto le tue risposte fino a quando non l'ho pubblicato. Sembra che tutti abbiamo coperto un terreno simile.
DMGregory

Per casualità di livello crittografico, consultare RNGCryptoServiceProvider, ma tenere presente che è molto lento e che è escluso da tutte le piattaforme .NET spogliate di Unity.
McGuireV10,

6

UnityEngine.Random è statico. Se si desidera creare più istanze di un generatore di numeri casuali, utilizzare System.Random.

Non è possibile cercare il codice sorgente per l'implementazione di Unity, tuttavia Microsoft fornisce l'origine per System.Random .


3
Non che la fonte di Microsoft non sia quella utilizzata da Unity. Dovresti invece guardare la fonte Mono.
Arturo Torres Sánchez,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.