ECS:隨機數


各個工作線程的隨機數種子是穩定的,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);
       randomArray[nativeThreadIndex] = rand;
// ... } } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM