各个工作线程的随机数种子是稳定的,RandomSystem的实现如下:
using Unity.Entities;
using Unity.Jobs;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs.LowLevel.Unsafe;
using Random = Unity.Mathematics.Random;
[UpdateInGroup( typeof(InitializationSystemGroup))]
public class RandomSystem : ComponentSystem
{
public NativeArray<Random> randomArray;
protected override void OnCreate()
{
base.OnCreate();
// JobsUtility.MaxJobThreadCount = 7 JobsUtility.MaxJobThreadCount = 128
randomArray = new NativeArray<Random>(JobsUtility.MaxJobThreadCount, Allocator.Persistent);
var seed = new System.Random();
for (int i = 0; i < randomArray.Length; ++i)
{
randomArray[i] = new Random((uint)seed.Next());
}
}
protected override void OnDestroy()
{
randomArray.Dispose();
base.OnDestroy();
}
protected override void OnUpdate()
{}
}
在其他的job中使用随机数,下面的代码去掉了冗余逻辑,只留下关键代码:
using UnityEngine;
using Unity.Entities;
using Unity.Transforms;
using Unity.Jobs;
using Unity.Burst;
using Unity.Mathematics;
using Unity.Collections;
using Unity.Jobs.LowLevel.Unsafe;
using Random = Unity.Mathematics.Random;
public partial class TestSystem : JobComponentSystem
{
private EndSimulationEntityCommandBufferSystem endSimulationECBS;
private EntityQueryDesc desc;
protected override void OnCreate()
{
endSimulationECBS = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
desc = new EntityQueryDesc()
{
All = new ComponentType[] { ComponentType.ReadOnly<Translation>(), ComponentType.ReadOnly<Rotation>() },
};
base.OnCreate();
}
protected override void OnDestroy()
{
base.OnDestroy();
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
EntityQuery query = GetEntityQuery(desc);
NativeArray<Entity> generateSkillEntities = new NativeArray<Entity>(query.CalculateEntityCount(), Allocator.TempJob);
TestJob job = new TestJob()
{
ecb = endSimulationECBS.CreateCommandBuffer().ToConcurrent(),
randomArray = World.GetExistingSystem<RandomSystem>().randomArray,
};
JobHandle handle = job.Schedule(this, inputDeps);
endSimulationECBS.AddJobHandleForProducer(handle);
return handle;
}
private struct TestJob : IJobForEachWithEntity<Translation, Rotation>
{
public EntityCommandBuffer.Concurrent ecb;
// 属性标签很重要
[NativeDisableParallelForRestriction]
public NativeArray<Random> randomArray;
// JOB_ID
[Unity.Collections.LowLevel.Unsafe.NativeSetThreadIndex]
private int nativeThreadIndex;
public void Execute(Entity entity, int index, [ReadOnly] ref Translation translation, [ReadOnly] ref Rotation rotation)
{
Random rand = randomArray[nativeThreadIndex];
float distance = rand.NextFloat(min, max);
// ...
}
}
}
来源:oschina
链接:https://my.oschina.net/u/4415723/blog/4463419