EntityCommandBufferSystem能使我们在System中创建/销毁Entity。
利用EntityCommandBufferSystem创建Entity
其实是利用EntityCommandBufferSystem将命令队列压入主线程执行。
1、首先设计Component:
using Unity.Entities;
public struct SpawnData : IComponentData
{
public int Count;
public Entity Template;
}
这个Component有什么用呢?后面我们将创建一个含上述Component的Entity,然后在System的OnUpdate中筛选出上述Entity,调用EntityCommandBuffer.Concurrent.Instantiate方法基于Template成员实例化出更多的Entity。
2、创建一个含上述Component的Entity:
其中,TemplateProvider:
using Container;
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;
public class TemplateProvider : MonoBehaviour, IDeclareReferencedPrefabs, IConvertGameObjectToEntity
{
[SerializeField] private GameObject Prefab;// SpawnData里面的模板
// IDeclareReferencedPrefabs接口
public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
{
referencedPrefabs.Add(Prefab);
}
// IConvertGameObjectToEntity接口
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var spawnerData = new SpawnData
{
Template = conversionSystem.GetPrimaryEntity(Prefab),
Count = 10
};
dstManager.AddComponentData(entity, spawnerData);
}
}
3、在System中实例化出更多Entity:
using Unity.Entities;
using Unity.Transforms;
public class SpawnSystem : SystemBase
{
// 开始初始化 实体命令 缓存系统
BeginInitializationEntityCommandBufferSystem beginInitEntityCommandBufferSystem;
protected override void OnCreate()
{
// 获取这个系统
beginInitEntityCommandBufferSystem
= World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
}
protected override void OnUpdate()
{
// 获取命令队列
var commandBuffer
= beginInitEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();
// 查找含SpawnData的Entity,把命令添加到命令队列
Entities.ForEach(
(Entity entity, int entityInQueryIndex, in SpawnData spawnData) =>
{
for (int i = 0; i < spawnData.Count; i++)
{
var instance = commandBuffer.Instantiate(
entityInQueryIndex, spawnData.Template);
commandBuffer.SetComponent(
entityInQueryIndex, instance, new Translation { Value = i * 5 });
}
// 生成后要删除,这样下一次就不会再创建了
commandBuffer.DestroyEntity(entityInQueryIndex, entity);
}).ScheduleParallel();
// 添加依赖
beginInitEntityCommandBufferSystem.AddJobHandleForProducer(Dependency);
}
}
利用EntityCommandBufferSystem销毁Entity
using Unity.Entities;
public struct LifeTime : IComponentData
{
public float Value;
}
public class LifeTimeSystem : SystemBase
{
// 声明用基类
EntityCommandBufferSystem m_Barrier;
protected override void OnCreate()
{
m_Barrier = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
}
protected override void OnUpdate()
{
var commandBuffer = m_Barrier.CreateCommandBuffer().ToConcurrent();
var deltaTime = Time.DeltaTime;
Entities.ForEach((Entity entity, int nativeThreadIndex, ref LifeTime lifetime) =>
{
lifetime.Value -= deltaTime;
if (lifetime.Value < 0.0f)
{
commandBuffer.DestroyEntity(nativeThreadIndex, entity);
}
}).ScheduleParallel();
m_Barrier.AddJobHandleForProducer(Dependency);
}
}