UnityECS学习日记十七:UnityECS多种组件类型

UnityECS的组件是专门用来存储数据的数据结构一般继承自IComponentData接口,当然Unity还提供了其他类型组件。

1.IShareComponentData 接口,定义共享数据组件。

using Unity.Entities;
using UnityEngine;

public struct OtherComponentData : IComponentData
{
}

//共享组件
public struct ShareComponentData : ISharedComponentData
{
    public Mesh mesh;
}

主要用于列如大量敌人有共同的材质或者网格时候存储数据的,他们不会产生复制,只会占用一块内存。Unity会自动将他们汇集成一个Chunk(块) 内(注意块也是有大小的),当拥有共享组件的实体修改了其共享组件中数据时,会从内存复制一份该共享组件来修改,并重新放入一个Chun(块)里。

注意:创建共享组件时,我们要选择那些不经常变动的组件作为共享组件,因为修改实体共享组件中的数据时,会导致这个实体被移动到新的Chunk(块)中,这种移动块的操作是比较消耗时间的。(修改普通组件的值是不会改变实体的Chunk的)共享实体可以节省内存,特别是大量创建相同物体时,但不要滥用,这也会降低效率。


2.ChunkComponent(块组件)块组件和共享组件有点类似,它俩的区别是:修改块组件的值不会导致实体被移动到新的Chunk(块),而是将实体所在块的所有实体的块组件的值也一起修改。(可以看做直接操作的块的 “根数据” )

public struct ChunkComponent : IComponentData
{

}

public class EntityNew : MonoBehaviour, IConvertGameObjectToEntity
{
    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        
        dstManager.AddChunkComponentData<ChunkComponent>(entity);
    }
}

3.ISytemStateComponent (状态组件) 接口,它继承自IComponentData接口。ECS中目前没有提供回调方法,列如当物体删除时我们想要回调知道他被删除了,而状态组件在实体被销毁时该组件是不会被删除的,除非主动去删除。

// 状态组件
public struct SystemStateComponent:ISystemStateComponentData
{

}

namespace Unity.Entities
{
    public interface ISystemStateComponentData : IComponentData
    {
    }
}

4.ISystemStateSharedComponentData(状态共享组件) ,同上,标记整个Chunk(块)

//共享状态组件
public struct SharedSystemStateComponent : ISystemStateSharedComponentData
{

}
namespace Unity.Entities
{
    public interface ISystemStateSharedComponentData : ISharedComponentData
    {
    }
}

5.IBufferElementData(动态队列/缓冲区/数组),实体身上不能同时挂载两个相同的组件,但是也提供了可以挂载的方式。

//可以被挂载多次的组件
public struct IBufferComponetData : IBufferElementData
{
    public int num;
}
namespace Unity.Entities
{
    public interface IBufferElementData
    {
    }
}


public class BufferMonobehaviour : MonoBehaviour
{
    public GameObject prefab;
    private void Start()
    {
        var entityManager = World.Active.EntityManager;
        Entity entity = GameObjectConversionUtility.ConvertGameObjectHierarchy(this.prefab, World.Active);
        entity = entityManager.Instantiate(entity);
        // 给实体添加一个缓冲队列
        DynamicBuffer<IBufferComponetData> dynamicBuffer = entityManager.AddBuffer<IBufferComponetData>(entity);
        //给该实体的缓冲队列添加数据
        dynamicBuffer.Add(new IBufferComponetData { num = 1 });
        dynamicBuffer.Add(new IBufferComponetData { num = 2 });
        dynamicBuffer.Add(new IBufferComponetData { num = 3 });

    }
}
//如何操作数据
public class BufferSystem : JobComponentSystem
{
    struct BufferJob : IJobForEachWithEntity_EB<IBufferComponetData>
    {
        public void Execute(Entity entity, int index, DynamicBuffer<IBufferComponetData> bufferDatas)
        {
            for (int i = 0; i < bufferDatas.Length; i++)
            {
                Debug.Log("===" + bufferDatas[i].num);
            }
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        BufferJob bufferJob = new BufferJob();
        JobHandle bufferHandle = bufferJob.Schedule(this, inputDeps);
        return bufferHandle;
    }
}

注意这里Job中的IJobForEachWighEntity_EB专门用来筛选这种类型的。


相关脚本参考项目中 Scene16_OtherComponent 文件夹:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值