TL;DR: Use PRNG.Instance for 10-15x faster random generation than UnityEngine.Random, with a rich API for vectors, colors, weighted selection, and more.
Unity Helpers provides 15+ high-performance pseudo-random number generators (PRNGs) through a unified IRandom interface. All generators pass standard statistical tests and are optimized for game development workloads.
usingWallstopStudios.UnityHelpers.Core.Random;// Create with specific seedPcgRandomseeded=newPcgRandom(seed:12345);// Generate reproducible sequencefor(inti=0;i<10;i++){Debug.Log(seeded.Next(0,100));// Same values every run}// Different seed = different sequencePcgRandomdifferent=newPcgRandom(seed:67890);
// 2D vectorsVector2v2=random.NextVector2();// Each component [0, 1)Vector2ranged2=random.NextVector2(-10f,10f);// Each component [-10, 10)// 3D vectorsVector3v3=random.NextVector3();Vector3ranged3=random.NextVector3(-5f,5f);
// Exact-average pseudo-random distribution:// long-run success rate remains 25%, but failure streaks increase the next chance.if(ExactAveragePrd.TryCreate(0.25f,outExactAveragePrdcritChance)){boolcriticalHit=critChance.Roll(random);}// Bad-luck protection / pity timer:// starts at 10%, adds 5% after each failure, and guarantees success after 10 failures.if(BadLuckProtection.TryCreate(0.10f,0.05f,10,outBadLuckProtectionrareDrop)){booldropped=rareDrop.Roll(random);}// Weighted shuffle bag:// each three-draw cycle contains exactly two common tickets and one rare ticket.WeightedShuffleBag<string>bag=new();bag.TryAdd("Common",2);bag.TryAdd("Rare",1);bag.TryNext(random,outstringreward);
ExactAveragePrd intentionally rejects very small non-zero targets below ExactAveragePrd.MinimumPositiveTargetChance; use BadLuckProtection or a WeightedShuffleBag<T> for ultra-rare rewards. The stateful helpers expose restore APIs (TrySetFailuresSinceSuccess, TryRestoreRemaining, and copy helpers for bag tickets) so save/load systems can persist pity and deck state explicitly.
Choose the helper by design goal:
Goal
Helper
Behavior
Preserve exact long-run chance while reducing streaks
ExactAveragePrd
Chance rises after failures by a solved coefficient and resets on success
Guarantee eventual success after a dry streak
BadLuckProtection
Chance ramps by a fixed amount and can force a success after N failures
Avoid repeated clumps in finite weighted sets
WeightedShuffleBag<T>
Draws without replacement until every weighted ticket has appeared
// Shuffle in placemyList.Shuffle(random);// Random elementTelement=random.NextOf(array);Telement2=random.NextOf(list);// Random indexintindex=random.Next(collection.Count);
usingWallstopStudios.UnityHelpers.Core.Random;// Create thread-local wrapper around any generatorThreadLocalRandom<PcgRandom>threadLocal=new();IRandomrandom=threadLocal.Value;// Per-thread instance
usingWallstopStudios.UnityHelpers.Core.Random;PerlinNoisenoise=newPerlinNoise(seed:42);// 2D noise (terrain, textures)floatvalue2D=noise.Noise(x,y);// Octave noise for more detailfloatoctaves=noise.OctaveNoise(x,y,octaves:4,persistence:0.5f);
// ✅ Good - cache the referenceprivateIRandom_random=PRNG.Instance;voidUpdate(){floatvalue=_random.NextFloat();}// ❌ Bad - creates new instance every framevoidUpdate(){PcgRandomrandom=newPcgRandom();// Allocation!floatvalue=random.NextFloat();}