UnityECS学习日记十一:UnityECS与Unity Job System使用

使用实体组件系统和作业系统一起使用让性能起飞!


案例九:UnityECS和Job系统模拟雨滴降落(Scne10)

脚本:PureJob_DropData

using Unity.Entities;

[System.Serializable]
public struct PureJob_DropData : IComponentData
{
    public int velocity;
    public float delayTime;
}

脚本:PureJob_Proxy

using UnityEngine;
using Unity.Entities;

public class PureJob_Proxy : MonoBehaviour, IConvertGameObjectToEntity
{
    public PureJob_DropData dropData;
    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        dstManager.AddComponentData<PureJob_DropData>(entity, dropData);
    }


}

脚本:PureJob_Main

using UnityEngine;
using Unity.Entities;
using Unity.Collections;
using Unity.Transforms;

public class PureJob_Main : MonoBehaviour
{
    public int createCount = 300;
    public GameObject prefab;                       // 雨滴预制体
    public int dropSpeed = 10;
    public int dropHeight = 50;
    public int insRnage = 40;                           // 生成范围

    private EntityManager entityManager;

    private NativeArray<Entity> entities;

    void Start()
    {
        this.CreateMain();
    }
    private void CreateMain()
    {
        // 创建预制体实体
        entityManager = World.Active.EntityManager;

        entities = new NativeArray<Entity>(createCount, Allocator.Persistent);

        Entity entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, World.Active);

        entityManager.Instantiate(entityPrefab, entities);

        //初始化数据

        for (int i = 0; i < createCount; i++)
        {
            entityManager.SetComponentData<PureJob_DropData>(entities[i], new PureJob_DropData
            {
                delayTime = UnityEngine.Random.Range(0, 10),
                velocity = UnityEngine.Random.Range(dropSpeed / 10, dropSpeed),
            });

            var num = UnityEngine.Random.insideUnitSphere* insRnage;
            num.y = dropHeight;
            entityManager.SetComponentData<Translation>(entities[i], new Translation
            {
                Value = num
            });
        }

    }


    private void OnDestroy()
    {
        entities.Dispose();
    }
}

脚本:PureJob_DropJobSystem

using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using Unity.Transforms;
using Unity.Collections;

public class PureJob_DropJobSystem : JobComponentSystem
{

    // Unity Job提供的获取实体组件的方法

    struct GravityJob : IJobForEach<PureJob_DropData, Translation>
    {
        [ReadOnly]
        public int minHeight;
        [ReadOnly]
        public float deltaTime;
        [ReadOnly]
        public int velocity;
        [ReadOnly]
        public int delay;
        public void Execute(ref PureJob_DropData dropData, ref Translation translation)
        {
            if (dropData.delayTime > 0)
            {
                dropData.delayTime -= deltaTime;
            }
            else
            {
                if (translation.Value.y < minHeight)
                {
                    translation.Value.y = 0;
                    dropData.velocity = velocity;
                    dropData.delayTime = delay;
                }
                else
                {
                    translation.Value.y -= dropData.velocity * deltaTime;
                }
            }
        }
    }


    public int minHeight = -100;                              // 下落最低值
    #region
    /*
    protected override void OnUpdate()
    {
        // 通过ECS提供的筛方式遍历场景中包含该数据组件的实体
        Entities.ForEach((ref Translation translation, ref DropData dropData) =>
        {

            if (dropData.delay > 0)
            {
                dropData.delay -= Time.deltaTime;
            }
            else
            {
                if (translation.Value.y < minHeight)
                {
                    translation.Value.y = 0;
                    dropData.velocity = Random.Range(1, 10);
                    dropData.delay = Random.Range(1, 10);
                }
                else
                {
                    translation.Value.y -= dropData.velocity * Time.deltaTime;
                }
            }
        });
    }
    */
    #endregion
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        GravityJob gravityJobSystem = new GravityJob
        {
            minHeight = minHeight,
            delay = UnityEngine.Random.Range(1, 10),
            velocity = UnityEngine.Random.Range(1, 10) * 10,
            deltaTime = Time.deltaTime
        };
        JobHandle jobHandle = gravityJobSystem.Schedule(this, inputDeps);
        jobHandle.Complete();
        return jobHandle;
    }


}

如上图,生成了10万个小球模拟雨滴下落,不同的Job在并行计算从而提高性能。注意: PureJob_DropJobSystem中可以看到,UnityECS为Job也提供了单独的筛选方式来获取实体~

 

远程项目仓库(github):https://github.com/h1031464180/UnityECS 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值