Entity Jobs接口
1.IJobEntity: 适合绝大多数情况使用
2.IJobChunk:
=========================================================================
通过预制体实例化Entity
namespace DOTS.DOD.LESSON3
{
struct CubeGeneratorByPrefab : IComponentData
{
//用于克隆实例的Entity
public Entity cubeEntityProtoType;
//控制Entity数量
public int cubeCount;
}
class CubeGeneratorByPrefabAuthoring : Singleton<CubeGeneratorByPrefabAuthoring> //单例模板抽象类
{
public GameObject cubePrefab = null;
[Range(1, 10)] public int CubeCount = 6;
//自定义数据Baker
class CubeBaker : Baker<CubeGeneratorByPrefabAuthoring>
{
public override void Bake(CubeGeneratorByPrefabAuthoring authoring)
{
AddComponent(GetEntity(TransformUsageFlags.Dynamic), new CubeGeneratorByPrefab //如何将组件覆盖到游戏实体
{
cubeEntityProtoType = GetEntity(authoring.cubePrefab, TransformUsageFlags.None),
cubeCount = authoring.CubeCount
});
}
}
}
}
同一个World只能使用一个Singleton Component,不同World可以有多个Singleton Component。
namespace DOTS.DOD.LESSON3
{
[BurstCompile]
//当实体的Query为空,跳过OnUpdate
[RequireMatchingQueriesForUpdate]
[UpdateInGroup(typeof(CreateEntitiesByPrefabSystemGroup))]
partial struct CubeGenerateByPrefabSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
//当CubeGeneratorByPrefab存在时,组件运行
state.RequireForUpdate<CubeGeneratorByPrefab>();
}
[BurstCompile]
public void OnDestroy(ref SystemState state)
{
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
//获取CubeGeneratorByPrefab生成器对象
var generator = SystemAPI.GetSingleton<CubeGeneratorByPrefab>();
//生成NativeArray数组
var cubes = CollectionHelper.CreateNativeArray<Entity>(generator.cubeCount, Allocator.Temp);
//实例化实例
state.EntityManager.Instantiate(generator.cubeEntityProtoType, cubes);
int count = 0;
foreach (var cube in cubes)
{
//添加旋转和移动数据
state.EntityManager.AddComponentData<RotateAndMoveSpeed>(cube, new RotateAndMoveSpeed
{
rotateSpeed = count*math.radians(60.0f),
moveSpeed = count
});
//设置每个Cube的初始位置
var position = new float3((count - generator.cubeCount * 0.5f) * 1.2f, 0, 0);
//var transform = SystemAPI.GetComponentRW<LocalTransform>(cube);
//Aspect下的一个子集??
var transform = SystemAPI.GetAspectRW<transformAspect>(cube);
transform.ValueRW.Position = position;
count++;
}
//销毁该临时数组
cubes.Dispose();
// 此System只在启动时运行一次,所以在第一次更新后关闭它。
state.Enabled = false;
}
}
}
(太难了,想呕吐🤮…)
Aspect相关属性和API如下:
个人对Aspect在查询上的理解,请大佬指正!!!
=========================================================================
Entity的随机访问
使用ComponentLookup :本质上是一个nativecontainer(数组容器??),访问方式类似数组,可以在Job工作线程中安全读取ComponentLookup,但一般并行情况情况下要避免写入ComponentLookup,除非你可以保证两个实例永远不会写入到容器中的同一索引(造成冲突),你可以使用NativeDisableParallelForRestrictionAttribute属性添加ComponentLookup的字段。例如以下这种情况:
补充;Job之外的随机访问
=========================================================================
EntityCommandBuffer
为什么要使用ECB,原因在于Job无法直接创建销毁Entity,也无法直接添加和删除组件
需要注意的知识点: