Комментарии 17
Имхо идеальное решение — иметь несколько ГПСЧ, по одному под каждое независимое активити со случайными числами — один под действия мобов, один под генерацию уровней, один под случайные события, один под генерацию урона мин-макс (а-ля стреляем 6-12, выпало 11), итд. UnityEngine.Random, судя по описанному, синглтон и подобное не позволяет, при этом логика ГПСЧ ломается установкой сида при генерации уровня и отсутствием переинициализации его после завершения. И ИМХО нафиг не надо сохранять старый seed, если требуется установить сид у синглтон-ГПСЧ в некое значение, просто потом взять сид откуда-нибудь ещё, вплоть до System.random или хэша от даты вместе с ним. Проще говоря, авторы игры неправильно использовали Random, но в самом рандоме проблем нет — он работает как надо. Но новый класс использовать необязательно, можно и имеющимся обойтись, просто поаккуратнее заниматься переинициализацией сида.
Как выше уже заметили, устанавливать seed нужно только в случае, если надо получать одинаковые последовательности случайных чисел. Это может быть удобно, например, для отладки.
Зачем вы трогали seed, если вам нужны разные случайные числа — непонятно.
5 экземпляров и 1мб памяти пропадает.
Это, мягко говоря, не так.
var start = GC.GetTotalMemory(true);
var rnd = new Random();
var rnd2 = new Random();
var rnd3 = new Random();
var rnd4 = new Random();
var rnd5 = new Random();
var stop = GC.GetTotalMemory(true);
Console.WriteLine(stop - start); // 1400 получается
Либо так, либо я что-то не правильно делаю.
Это может быть удобно, например, для отладки.Еще это иногда используется чтобы игрок не мог перекрутить вероятности в свою пользу перезагрузив сохранение.
Все проблемы не из-за статичности UnityEngine.Random
, а из-за того, что кто-то не разбираясь воткнул первое что под руку подвернулось.
Нет никаких проблем с тем чтобы использовать ГПСЧ, seed для которого задаётся глобально, но этот seed должен задаваться один раз для проекта. Это нормальное архитектурное решение, потому что нередко нужен генератор псевдослучайных событий, но при этом нет необходимости в воспроизведении состояния. Такой подход используется во многих языках и библиотеках.
Поэтому надо не "перестать использовать UnityEngine.Random", а начать читать документацию и использовать инструменты для тех целей, для которых они предназначены, только и всего. Нужно сохранение состояния — используй подходящий генератор.
Стоит отметить, что MCG, LCG и товарищи, хоть и (относительно) быстрые, но стоит отметить, что энтропия у них хуже, чем у xorshift, который судя по отзывам используется в UnityEngine.Random
, и ГПСЧ в System.Random
. Это вряд ли кто-либо заметит, впрочем.
начать читать документацию и использовать инструменты для тех целей, для которых они предназначены
В документации нет ни слова о предназначении.
В целом совет не плохой, воспользуйтесь им.
Нет никаких проблем с тем чтобы использовать ГПСЧ, seed для которого задаётся глобально
Согласен, но проблема появится тогда, когда он перестанет быть единственным.
Да, важно — сид не трогать. Его вообще не должно быть видно вне тестов.
Script 'Packages/fastrandom/src/RandomSeed.cs' will not be compiled because it exists outside the Assets folder and does not to belong to any assembly definition file.
UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget, String[])
private double InternalSample()
{
var ret = _next * ModulusReciprocal;
_next = _next * Multiplier % Modulus;
return ret;
}
Если нужно больше, сделайте собственную реализацию интерфейса IRandom.
Долго выбирая сколько реализаций предоставлять (я рассмотрел около 10), остановился на том, что чем проще, тем лучше. Для всего остального есть интерфейс.
Вы в ответе за тех, кого приручили. Было бесчисленное количество ошибок, связанное с тем, что люди делали какой-то функционал для базовых сценариев, а все их использовали для других. Поэтому как раз в .NET и заюзали для этого не самый быстрый, но зато достаточно «случайный» метод Фиббоначи с запаздыванием. Чтобы как раз, кому надо быстроту, мог использовать и ЛКГ, а кому пофиг на всё — не ловил бы проблем из-за некачественной базовой реализации.
В моем случае она пришла, когда проставили seed в UE.Random.
Я хотел привлечь внимание к тому, что сделать случайность не случайной проще через реализацию, предоставляемую разработчиком движка. Я предоставил интерфейс, который можно свободно использовать и добавлять реализации, которые будут удовлетворять критериям доменной области.
Подумать за всех? Окей, добавлю SLPNG, но это не поможет решить проблему с использованием UE.Random.
Перестаньте использовать UnityEngine.Random