Яка різниця між 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?

Відповіді:


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

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

Однак, є випадки, коли ви хочете використовувати інші джерела випадковості:

  • Якщо ви використовуєте кілька потоків, у кожного потоку має бути власне джерело псевдовипадковості, щоб уникнути суперечок (UnityEngine.Random доступний лише в основній темі)

  • Якщо вам потрібна детермінована псевдовипадкова послідовність (наприклад, для генератора насінного рівня), ви, ймовірно, захочете, щоб ця система мала власне джерело псевдовипадковості, до якого жоден інший скрипт не може отримати доступ, так що відмінності в порядку виконання не спричиняють її пропустити числа і порушити детермінізм, на який ти розраховував. Для отримання додаткової інформації у блозі Unity є чудовий пост про висіяні випадкові числа .

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


Ну, вибачте ДжошПетрі та Йона - я певний час набирав це по мобільному, тому я не бачив ваших відповідей, поки не опублікував. Схоже, ми всі накрили подібну землю.
DMGregory

Про випадковість криптовалют див. RNGCryptoServiceProvider, але майте на увазі, що це дуже повільно і що він виключається з усіх позбавлених .NET платформ Unity.
McGuireV10

6

UnityEngine.Random є статичним. Якщо ви хочете створити кілька екземплярів генератора випадкових чисел, тоді ви хочете використовувати System.Random.

Немає можливості шукати вихідний код для впровадження Unity, однак Microsoft надає джерело для System.Random .


3
Не те, що джерело Microsoft не є тим, яким користується Unity. Ви повинні замість цього поглянути на джерело Mono.
Артуро Торрес Санчес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.