安装ECS三件套
直接上图,可以看到到目前为止还是Preview版本,Unity的DOTS(数据导向的技术堆栈)的技术堆栈这里就不讲了,很多大牛都有介绍,主要记录一下这个简单的demo
咱们初学者,先去学习学习官方demo,下面是链接:ECSSamples
先看看效果
红色的为LOD0,黄色LOD1,绿色LOD2,隐藏的LOD3
目标
1、使用ECS生成10000个小模型
2、使用LOD进一步优化性能
当然这里demo 数量级还比较小 没有lod 也完全能带的动
1、生成10000个小模型
//这个生成10000个模型在理解了ECS基本原理之后来看比较简单,就贴点代码
//直接使用的ECSSamples里面的代码
//将Prefab转换为Entity对象
public class Spawner_FromEntity : MonoBehaviour, IDeclareReferencedPrefabs, IConvertGameObjectToEntity
{
public GameObject Prefab;
public int CountX;
public int CountY;
public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
{
referencedPrefabs.Add(Prefab);
}
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var spawnerData = new SpawnerComp_FormEntity
{
Prefab = conversionSystem.GetPrimaryEntity(Prefab),
CountX = CountX,
CountY = CountY
};
dstManager.AddComponentData(entity, spawnerData);
}
}
//Component定义
public struct SpawnerComp_FormEntity: IComponentData
{
public Entity Prefab;
public int CountX;
public int CountY;
}
//创建Entity的System
[UpdateInGroup(typeof(SimulationSystemGroup))]
public class SpawnerSystem_FromEntity: SystemBase
{
//这里理解可能需要去看一看几种CommanBufferSystem的调度原理
private BeginInitializationEntityCommandBufferSystem m_EntityCommandBufferSystem;
protected override void OnCreate()
{
m_EntityCommandBufferSystem = World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
}
protected override void OnUpdate()
{
var commandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer().AsParallelWriter();
Entities
.WithName("SpawnerSystem_FromEntity")
.WithBurst(FloatMode.Default, FloatPrecision.Standard, true)
.ForEach((Entity entity, int entityInQueryIndex, in SpawnerComp_FormEntity spawnerCompFormEntity, in LocalToWorld location) =>
{
for (var x = 0; x < spawnerCompFormEntity.CountX; x++)
{
for (var y = 0; y < spawnerCompFormEntity.CountY; y++)
{
var instance = commandBuffer.Instantiate(entityInQueryIndex, spawnerCompFormEntity.Prefab);
// Place the instantiated in a grid with some noise
var position = math.transform(location.Value,
new float3(x * 1.3F, noise.cnoise(new float2(x, y) * 0.21F) * 2, y * 1.3F));
commandBuffer.SetComponent(entityInQueryIndex, instance, new Translation {Value = position});
}
}
commandBuffer.DestroyEntity(entityInQueryIndex, entity);
}).ScheduleParallel();
// SpawnJob runs in parallel with no sync point until the barrier system executes.
// When the barrier system executes we want to complete the SpawnJob and then play back the commands (Creating the entities and placing them).
// We need to tell the barrier system which job it needs to complete before it can play back the commands.
m_EntityCommandBufferSystem.AddJobHandleForProducer(Dependency);
}
}
2、LOD
这个是我的Prefab面板,看到我使用了一个Automatic LOD,自动见面生成不同等级LOD Mesh,挺好用推荐一下 Assetstore地址
挂上Automatic LOD,Switch Mode=Unity LOD Group
点击Gennerate LODs,就生成完成了,
较复杂的模型,涉及UV错误 和 边界保护等的,Swich by Unity LOD Group 的话没有去测试,有需求的小伙伴可以用自己模型测试测试
生成了四个层级的LOD,Entity是支持LOD Group的;
结束
就写到这里,demo比较简单,但是对于初次接触ECS以及LOD的小伙伴,应该还是能起到一些帮助的。