UnityECS学习日记五:Hybrid(混合)ECS

案例四:Hybrid(混合)ECS动态创建指定数量的小球Entity(实体)(Scne5)

Hybrid编程 GameObject转变为实体,使用unity的预制体来动态创建数量级雨滴下落。在上篇的基础上,将Unity预制体加入代理来实现。

 脚本:DropData_Hybrid

using Unity.Entities;

[System.Serializable]
public struct DropData_Hybrid : IComponentData
{
    public float delay;
    public float velocity;
}

脚本:DropSystem_Hbrid

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

public class DropSystem_Hybrid : ComponentSystem
{
    public float minHeight = -100;                              // 下落最低值
    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;
                }
            }
        });
    }
}

代理脚本:DropDataProxy_Hybrid

using UnityEngine;
using Unity.Entities;

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

脚本:Hybrid_DropMain

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

public class Hybrid_DropMain : MonoBehaviour
{
    public int entityCount = 1000;
    public int entityRange = 100;
    public int delaySpeed = 1;
    public int dropSpeed = 1;
    public Mesh mymesh;
    public Material mymaterial;
    public GameObject prefab;
    void Start()
    {
        this.CreatePureMain();
    }

    void CreatePureMain()
    {
        #region  1.创建本地实体数组
        // 世界自动创建的唯一实体管理器
        EntityManager entityManager = World.Active.EntityManager;

        NativeArray<Entity> entities = new NativeArray<Entity>(entityCount, Allocator.Temp);

        /*  这里不需要手动创建实体原型了
        // 创建一个原型模型(可以类比   GameObject.CreatePrimitive ), 函数参数代表该实体有哪些组件(注意要想实体在场景中显示必须有 Translation,RenderMesh,LoalToWorld这三个组件)
        EntityArchetype entityArchetype = entityManager.CreateArchetype
        (
            typeof(Translation),
            typeof(RenderMesh),
            ComponentType.ReadWrite<LocalToWorld>(),                     // 实体的矩阵,
            ComponentType.ReadOnly<DropData>()                             // 
        );
        entityManager.CreateEntity(entityArchetype, entities);
        */

        // unity 以提供了一个转换实体的公共类 
        Entity entity = GameObjectConversionUtility.ConvertGameObjectHierarchy(this.prefab, World.Active);
        // 然后对这个实体进行实例化 想象成 Instantiate
        entityManager.Instantiate(entity, entities);

        #endregion

        #region 2.初始化数组中的实体数据

        for (int i = 0; i < entityCount; i++)
        {
            // 初始化位置信息
            Translation translation = new Translation();
            translation.Value = Random.insideUnitSphere * entityRange;                      // 设置位置为随机的球体
            translation.Value.y = 0;
            entityManager.SetComponentData<Translation>(entities[i], translation);  // 设置位置信息

            // 初始化延迟时间
            entityManager.SetComponentData<DropData>(entities[i], new DropData { delay = Random.Range(1, 10), velocity = Random.Range(1, 100) });

            // 因为使用的预制体 这里不再需要手动设置网格信息
            // 给所有实体 设置网格 和材质 信息 这些UnityECS做了优化处理,使用共享网格材质的函数进行添加
            //entityManager.SetSharedComponentData<RenderMesh>(entities[i], new RenderMesh { mesh = mymesh, material = mymaterial });
        }

        entities.Dispose();     // 这里把内存缓冲区释放掉
        #endregion
    }
}

如下图,将球体设置为预制体,将代理脚本挂在到其身上。注意添加ConvertToEntity脚本。 

 将预制体拖到Hybrid_DropMain的初始化prefab变量,如下图通过预制体方式生成了10万个小球,与上篇Stats数据相比:Batches增加了将近1万的batche,因为预制体上还有碰撞器,旋转信息等不必要的组件。这可以看出两者的性能区别之处!

 

 

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值