Qual é a diferença entre UnityEngine.Random e System.Random?

24

Qual a diferença entre isso

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

e isto

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

Eu sei System.Randomque sempre deve ser inicializado na parte superior da sua classe UnityEngine.Random. Sei também que System.Randomfunciona com um "relógio" interno e o número "aleatório" é baseado nisso.

Minha pergunta agora é: existe alguma outra diferença entre UnityEngine.Randome System.Randome o código de bruxa é melhor usar para um projeto do Unity?

H. Pauwelyn
fonte

Respostas:

23

Indiscutivelmente a diferença mais importante é que o Unity Random.Rangeé um pouco mais fácil de usar, sendo estático. A biblioteca de classes base C # System.Random, no entanto, oferece mais controle e isolamento.

É possível que eles também usem diferentes implementações secretas (embora meu palpite seja que o Unity's Randomseja implementado apenas em termos de sistema Random), mas isso provavelmente não é uma preocupação notável. Fundamentalmente, ambos são provavelmente o mesmo tipo de gerador de números aleatórios: um gerador pseudo-aleatório baseado na iteração de uma sequência definida por alguma semente).

A questão do controle é mais relevante, porque em alguns contextos você pode querer usar fluxos aleatórios diferentes para coisas diferentes. Por exemplo, em um contexto de rede de rede com etapas de bloqueio, convém corrigir a semente usada para gerar eventos aleatórios que afetam a jogabilidade em todos os jogadores do jogo, mas talvez você não se importe tanto com o fluxo de números aleatórios usados ​​puramente eventos visuais e pode permitir que esse fluxo seja propagado de maneira mais tradicional (com o tempo de atividade do sistema no lançamento do jogo, por exemplo).

Da mesma forma, se você estiver gerando números aleatórios em vários segmentos, convém usar objetos aleatórios distintos para cada segmento, a fim de evitar condições de corrida. Isso pode surgir se a lógica do seu jogo passar por vários segmentos e você também tiver um sistema de repetição de jogabilidade, por exemplo.

No final, não é necessariamente melhor usar um ou outro em geral, mas existem prós e contras. Quando você precisar isolar a sequência de números de outras possíveis sequências aleatórias que possam estar acontecendo, ou quando precisar de controle localizado sobre a semente da sequência, use uma instância de System.Random. Se você só precisa de um valor aleatório rápido e sujo para um uso descartável ou algum outro cenário sem impacto, a simplificação do Unity Randomprovavelmente está correta.

Josh
fonte
3
Uma coisa que alguns jogos fazem é salvar o valor inicial quando o jogador salva o jogo. Dessa forma, as mesmas ações levam às mesmas consequências. Isso desencoraja a economia de escória e, se você se esqueceu de economizar posteriormente, pode voltar para onde estava antes. O último XCOM fez isso.
precisa saber é o seguinte
3
@GregRos Boa nota, mas pode introduzir um tipo diferente de economia de economia, conforme descrito neste artigo - basicamente, em vez de tentar novamente o mesmo movimento até obter sucesso, o jogador tenta diferentes seqüências de movimentos até os movimentos que mais se preocupam com a maioria das terras em rolos bem-sucedidos na sequência predeterminada. Acontece que há maneiras de economizar em qualquer sistema com salvamentos. Scummers Gonna Scum, então às vezes faz sentido acompanhar o fluxo como o XCOM .
DMGregory
10

O UnityEngine.Random possui algumas vantagens de facilidade de uso:

  • Estático / acessível globalmente - você não precisa criar uma instância para cada objeto ou sistema que precise de aleatoriedade. A maioria ou todos os seus scripts podem compartilhar esse recurso.

  • Métodos de conveniência - você pode usar Random.Range (), Random.insideUnitSphere, Random.rotationUniform, Random.ColorHSV () para obter valores aleatórios bem distribuídos de vários tipos úteis sem precisar rolar sua própria matemática.

(Não encontrei nenhuma confirmação sobre se o UnityEngine.Random fornece garantias de consistência entre plataformas diferentes da implementação Mono do System.Random - elas podem ou não ser a mesma coisa)

É claro que você pode criar sua própria classe que usa System.Random (ou outra biblioteca ou seu próprio PRNG) para fazer isso, mas a parte boa é que você não precisa - a implementação do Unity visa fornecer uma boa linha de base para comportamento aleatório fora da caixa.

Dito isto, há casos em que você deseja usar outras fontes de aleatoriedade:

  • Se você estiver usando vários encadeamentos, cada encadeamento deve ter sua própria fonte de pseudo-aleatoriedade para evitar contendas (o UnityEngine.Random só pode ser acessado no encadeamento principal)

  • Se você precisar de uma sequência pseudo-aleatória determinística (por exemplo, para um gerador de nível inicial), provavelmente desejará que esse sistema tenha sua própria fonte de pseudo-aleatoriedade que nenhum outro script possa acessar, para que diferenças na ordem de execução não o façam. pule números e quebre o determinismo com o qual estava contando. Para mais informações, há um ótimo post no blog do Unity sobre números aleatórios semeados .

  • se você precisar de aleatoriedade criptograficamente forte para segurança, jogos de azar ou geração de IDs únicos, use bibliotecas especializadas para esse fim. Nem o UnityEngine.Random nem o System.Random fornecem garantias de qualidade suficientes.

DMGregory
fonte
Opa, desculpas a JoshPetrie e Jon - demorei um pouco digitando isso no celular, então não vi suas respostas até publicá-la. Parece que todos nós já cobrimos terreno semelhante.
DMGregory
Para aleatoriedade de criptografia, consulte RNGCryptoServiceProvider, mas lembre-se de que é muito lento e é excluído de todas as plataformas .NET despojadas do Unity.
McGuireV10
6

UnityEngine.Random é estático. Se você deseja criar várias instâncias de um gerador de números aleatórios, use System.Random.

Não há como procurar o código-fonte para a Implementação da Unity, no entanto, a Microsoft fornece a fonte para System.Random .

jgallant
fonte
3
Não que a fonte da Microsoft não seja a usada pelo Unity. Você deve procurar a fonte Mono.
Arturo Torres Sánchez