Random Numbers inside Unity Jobs
Feb 24, 2022
Unity's job system is fast but because it's multithreaded using random numbers inside a job is tricky. Here's one way to do it.
using UnityEngine;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
public class Obj {
NativeArray<Unity.Mathematics.Random> randomNumberGenerators;
void Awake() {
randomNumberGenerators = new NativeArray<Unity.Mathematics.Random>(Unity.Jobs.LowLevel.Unsafe.JobsUtility.MaxJobThreadCount, Allocator.Persistent);
for (int i = 0; i < randomNumberGenerators.Length; i++) {
randomNumberGenerators[i] = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, int.MaxValue));
}
}
public void RunJob() {
NativeArray<float3> positions = new NativeArray<float3>(1000, Allocator.TempJob);
ObjJob job = new ObjJob {
randomNumberGenerators = randomNumberGenerators,
positions = positions
};
job.Schedule(positions.Length, 32).Complete();
// do something with random positions
positions.Dispose();
}
}
[BurstCompile]
struct ObjJob : IJobParallelFor
{
[Unity.Collections.LowLevel.Unsafe.NativeDisableContainerSafetyRestriction] public NativeArray<Unity.Mathematics.Random> randomNumberGenerators;
[Unity.Collections.LowLevel.Unsafe.NativeSetThreadIndex] int threadId;
[WriteOnly] public NativeArray<float3> positions;
public void Execute(int i) {
Unity.Mathematics.Random random = randomNumberGenerators[threadId];
positions[i] = new float3(random.NextFloat(), random.NextFloat(), random.NextFloat());
randomNumberGenerators[threadId] = random;
}
}