Quelle est la différence entre UnityEngine.Random et System.Random?


24

Quelle est la différence entre cela

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

et ça

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

Je sais qu'il System.Randomfaut toujours initialiser sur le dessus de votre classe ce qui UnityEngine.Randomn'est pas nécessaire. Je sais aussi que cela System.Randomfonctionne avec une "horloge" interne et le nombre "aléatoire" est basé sur cela.

Ma question est maintenant y a-t-il une autre différence entre UnityEngine.Randomet System.Randomet le code sorcier est préférable d'utiliser pour un projet Unity?

Réponses:


23

La différence la plus importante est sans doute que l'Unity Random.Rangeest légèrement plus facile à utiliser, étant statique. System.RandomCependant, la bibliothèque de classes de base C # vous offre plus de contrôle et d'isolement.

Il est possible qu'ils utilisent également différentes implémentations sous le capot (bien que je suppose que l'Unity Randomest simplement implémenté en termes de système Random), mais ce n'est probablement pas une préoccupation notable. Fondamentalement, ils sont probablement tous deux le même type de générateur de nombres aléatoires: un générateur pseudo-aléatoire basé sur l'itération d'une séquence définie par une graine).

Le problème de contrôle est plus pertinent, car dans certains contextes, vous souhaiterez peut-être utiliser différents flux aléatoires pour différentes choses. Par exemple, dans un contexte de mise en réseau de mise en réseau à étape de verrouillage, vous souhaiterez peut-être corriger la graine utilisée pour générer des événements aléatoires affectant le gameplay sur tous les joueurs du jeu, mais vous ne vous souciez peut-être pas tant du flux de nombres aléatoires utilisé uniquement pour les événements visuels et peuvent permettre à ce flux d'être semé d'une manière plus traditionnelle (avec la disponibilité du système au lancement du jeu, par exemple).

De même, si vous allez générer des nombres aléatoires dans plusieurs threads, vous souhaiterez peut-être utiliser des objets aléatoires distincts pour chaque thread afin d'éviter les conditions de concurrence. Cela peut arriver si votre logique de jeu traverse de nombreux threads et que vous avez également un système de rejeu de jeu, par exemple.

Au final, il n'est pas forcément préférable d'utiliser l'un ou l'autre en général, il y a plutôt des avantages et des inconvénients. Lorsque vous devez isoler la séquence de nombres des autres séquences aléatoires potentielles qui peuvent se produire, ou lorsque vous avez besoin d'un contrôle localisé sur la graine de la séquence, utilisez une instance de System.Random. Si vous avez juste besoin d'une valeur aléatoire rapide et sale pour une utilisation jetable ou un autre scénario sans impact, la simplification d'Unity Randomest probablement très bien.


3
Certains jeux permettent de sauvegarder la valeur de départ lorsque le joueur sauvegarde le jeu. De cette façon, les mêmes actions entraînent les mêmes conséquences. Cela décourage la sauvegarde de l'écume, et si vous avez oublié de sauvegarder plus tard, vous pouvez simplement revenir là où vous étiez auparavant. Le dernier XCOM l'a fait.
GregRos

3
@GregRos Bonne note, mais cela peut introduire un type de sauvegarde différent comme décrit dans cet article - fondamentalement, au lieu de réessayer le même coup jusqu'à ce qu'ils réussissent, le joueur essaie différentes séquences de coups jusqu'à ce que les mouvements qui lui tiennent le plus à cœur sur les jets réussis dans la séquence prédéterminée. Il s'avère qu'il existe des moyens de sauvegarder dans n'importe quel système avec des sauvegardes. Scummers Gonna Scum, donc parfois il est logique de suivre le flux comme XCOM l'a fait .
DMGregory

10

UnityEngine.Random présente quelques avantages en termes de facilité d'utilisation:

  • Statique / accessible globalement - vous n'avez pas besoin de créer une instance pour chaque objet ou système qui a besoin d'aléatoire. La plupart ou la totalité de vos scripts peuvent partager cette ressource.

  • Méthodes pratiques - vous pouvez utiliser Random.Range (), Random.insideUnitSphere, Random.rotationUniform, Random.ColorHSV () pour obtenir des valeurs aléatoires bien réparties de divers types utiles sans avoir à utiliser vos propres calculs.

(Je n'ai trouvé aucune confirmation si UnityEngine.Random fournit des garanties de cohérence multiplateforme différentes de l'implémentation Mono de System.Random - elles peuvent ou non être les mêmes sous le capot)

Vous pouvez bien sûr créer votre propre classe qui utilise System.Random (ou une autre bibliothèque, ou votre propre PRNG) pour ce faire, mais la bonne partie est que vous n'en avez pas besoin - L'implémentation d'Unity est destinée à vous donner une bonne base de référence pour comportement aléatoire hors de la boîte.

Cela dit, il y a des cas où vous voudrez utiliser d'autres sources de hasard:

  • Si vous utilisez plusieurs threads, chaque thread doit avoir sa propre source de pseudo-aléatoire pour éviter les conflits (UnityEngine.Random n'est accessible que sur le thread principal)

  • Si vous avez besoin d'une séquence pseudo-aléatoire déterministe (par exemple pour un générateur de niveau prédéfini), vous voudrez probablement que ce système ait sa propre source de pseudo-aléatoire à laquelle aucun autre script ne peut accéder, de sorte que les différences dans l'ordre d'exécution ne le provoquent pas. sautez les chiffres et brisez le déterminisme sur lequel vous comptiez. Pour plus d'informations, il y a un excellent article sur le blog Unity sur les nombres aléatoires prédéfinis .

  • si vous avez besoin d'un caractère aléatoire cryptographiquement fort pour la sécurité, le jeu ou la génération d'ID uniques, vous devez utiliser des bibliothèques spécialisées à cet effet. Ni UnityEngine.Random ni System.Random n'offrent des garanties de qualité suffisantes.


Oups, excuses à JoshPetrie et Jon - J'ai mis du temps à taper ceci sur mobile, donc je n'ai pas vu vos réponses avant de l'avoir posté. On dirait que nous avons tous couvert un terrain similaire.
DMGregory

Pour le caractère aléatoire de niveau cryptographique, voir RNGCryptoServiceProvider, mais gardez à l'esprit qu'il est très lent et qu'il est exclu de toutes les plates-formes .NET supprimées d'Unity.
McGuireV10

6

UnityEngine.Random est statique. Si vous souhaitez créer plusieurs instances d'un générateur de nombres aléatoires, vous souhaitez utiliser System.Random.

Il n'existe aucun moyen de rechercher le code source pour l'implémentation Unity, cependant, Microsoft fournit la source de System.Random .


3
Non pas que la source de Microsoft ne soit pas celle utilisée par Unity. Vous devriez plutôt regarder la source Mono.
Arturo Torres Sánchez
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.