ECS问题记录
开发过程中所遇到问题
-
如何存放Unity引用对象?(材质、网格)
目前知道的,只能在ISharedComponentData中存放Unity引用对象,且还需要继承IEquatable<T>接口,并实现Equals与GetHashCode方法。
-
如何修改单个物体的共享组件(ISharedComponentData)值。
由共享组件设计可以得知,在给Entity设定相同参数的共享组件时,这些Entity实际上都指向同一地址,也就是说,本质上只有一个共享组件,所以无论你修改任何Entity的ISharedComponentData参数,其他Entity也会发生改变。
修改ISharedComponentData参数的唯一办法,就是再创建一个ISharedComponentData,然后将该组件设置给Entity。
-
如何使用EntityQuery筛选组件相同,但组件参数不同的Entity。
暂时不知道是什么原因,我们定义了两个EntityQuery字段,且New了一个新的EntityQueryDesc,但当我们筛选相同类型组件(其中某个组件值进行了特定筛选),他们筛选出来的结果却是相同的,就像两个EntityQuery指向的是同一地址。
解决办法也非常奇特,就是在筛选条件下额外添加一个筛选组件条件,只要两个EntityQuery筛选条件的组件个数类型不相等,那么他们筛选出的结果就肯定不相同。
-
如何在Job中增添删除Entity的组件。
这里需要用到EndSimulationEntityCommandBufferSystem。
在OnCreate方法中创建EndSimulationEntityCommandBufferSystem:
private EndSimulationEntityCommandBufferSystem m_EntityCommandBufferSystem; protected override void OnCreate() { m_EntityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>(); }
然后在OnUpdate中使用,删除Entity
var commandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer(); ...... commandBuffer.DestroyEntity(entity);
-
如何用一组Entity去比较另一组Entity?
多种方法,第一种,在Entities.ForEach()嵌套使用Entities.ForEach()(看了网上教程才知道还可以这样用)
第二种,使用两个EntityQuery对Entity进行筛选,然后使用EntityQuery.ToEntityArray(Allocator.TempJob)方法转换成NativeArray<Entity>,后面直接对数组进行比较操作就可以了
-
如何通过Entity获取其身上的组件。
方法如下:
UnitCombatComponent EnemyCombatComponent = EntityManager.GetComponentData<UnitCombatComponent>(entity);
-
如何修改物体的颜色
一开始我在做Demo的时候也很想修改,直到我发现ECS用于渲染的组件RenderMesh是共享组件后我傻了。
然后我专念自己创建组件进行手动渲染:
using Unity.Entities; using UnityEngine; using System; struct UnitRenderMeshComponent : ISharedComponentData, IEquatable<UnitRenderMeshComponent> { public Mesh mesh; public int layer; public bool Equals(UnitRenderMeshComponent other) { return other.mesh == this.mesh; } public override int GetHashCode() { return mesh.GetHashCode(); } } struct UnitRenderMaterialComponent : ISharedComponentData, IEquatable<UnitRenderMaterialComponent> { public Material material; public bool Equals(UnitRenderMaterialComponent other) { return other.material == this.material; } public override int GetHashCode() { return material.GetHashCode(); } }
[UpdateInGroup(typeof(UpdatePresentationSystemGroup))] public class UnitRenderMeshSystem : SystemBase { protected override void OnUpdate() { Entities.ForEach((UnitRenderMeshComponent renderMesh, UnitRenderMaterialComponent renderMater, LocalToWorld localToWorld) => { Graphics.DrawMesh(mesh: renderMesh.mesh, matrix: localToWorld.Value, material: renderMater.material, layer: renderMesh.layer); }).WithoutBurst().Run(); } }
但这样还是很麻烦,每次像修改物体颜色,需要重新创建UnitRenderMaterialComponent组件,然后赋值新的材质。
-
Entity顺序问题。
在Entity中顺序并不是固定的。我们知道Entity所携带组件发生改变时会改变其所在的块,由于块发生了改变,所以entity在总体的数组中的Index也会随之发生改变。
一些知识点参考网址
EntityQuery:https://blog.csdn.net/weixin_40124181/article/details/103855181
System执行顺序:http://www.benmutou.com/archives/2823
各种Component:http://www.benmutou.com/archives/2840
Schedule相关:https://www.cnblogs.com/tiancaiwrk/p/12410825.html
网友评论