В чем разница между 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.Randomи System.Randomи ведьмой код лучше использовать для проекта Unity?

H. Pauwelyn
источник

Ответы:

23

Возможно, наиболее важным отличием является то, что Unity Random.Rangeнемного проще в использовании, будучи статичным. Библиотека базовых классов C # System.Random, однако, предлагает вам больше контроля и изоляции.

Возможно, что они также используют различные скрытые реализации (хотя я предполагаю, что 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 какие-либо межплатформенные гарантии согласованности, отличные от Mono-реализации System.Random - они могут или не могут быть одинаковыми под капотом)

Конечно, вы можете создать свой собственный класс, который использует System.Random (или другую библиотеку, или ваш собственный PRNG) для этого, но приятная часть в том, что вам это не нужно - реализация Unity предназначена для того, чтобы дать вам хороший базовый уровень для случайное поведение из коробки.

Тем не менее, есть случаи, когда вы захотите использовать другие источники случайности:

  • Если вы используете несколько потоков, каждый поток должен иметь свой собственный источник псевдослучайности, чтобы избежать конфликтов (UnityEngine.Random доступен только в основном потоке)

  • Если вам нужна детерминированная псевдослучайная последовательность (например, для генератора с затравочным уровнем), вы, вероятно, захотите, чтобы эта система имела собственный источник псевдослучайности, к которому не может получить доступ ни один другой сценарий, чтобы различия в порядке выполнения не приводили к ее пропустите цифры и сломайте детерминизм, на который вы рассчитывали. Для получения дополнительной информации в блоге Unity есть отличный пост о случайных числах .

  • если вам нужна криптографически сильная случайность для безопасности, азартных игр или генерации уникальных идентификаторов, вам следует использовать специализированные библиотеки для этой цели. Ни UnityEngine.Random, ни System.Random не предоставляют достаточных гарантий качества.

Д.М.Григорий
источник
Ой, извиняюсь перед ДжошПетри и Джоном - я потратил некоторое время на то, чтобы набрать это на мобильном телефоне, поэтому я не видел ваших ответов, пока не опубликовал это. Похоже, мы все прошли одинаковую работу.
DMGregory
Для получения информации о случайности криптографического уровня см. RNGCryptoServiceProvider, но имейте в виду, что он очень медленный и исключен из всех раздетых платформ Unity .NET.
McGuireV10
6

UnityEngine.Random является статическим. Если вы хотите создать несколько экземпляров генератора случайных чисел, вы можете использовать System.Random.

Невозможно найти исходный код для реализации Unity, однако Microsoft предоставляет источник для System.Random .

jgallant
источник
3
Не то чтобы источник Microsoft не тот, который используется Unity. Вы должны смотреть на источник Mono вместо этого.
Артуро Торрес Санчес