一、WriteGroup基础知识
WriteGroup是一个属性标签,在ECS的代码中可以用于修饰组件;
格式如下:
[WriteGroup(typeof(T))]
那么接下来看几段代码进行理解;
1、定义几个组件
struct ScaleComponentData : IComponentData
{
public Entity prefab;
public float3 scale;
public float3 pos;
}
/// <summary>
/// 放大Tag
/// </summary>
[WriteGroup(typeof(ScaleComponentData))]
struct BigScaleTag : IComponentData { }
/// <summary>
/// 缩小Tag
/// </summary>
[WriteGroup(typeof(ScaleComponentData))]
struct SmallScaleTag : IComponentData { }
}
1.1 拆分理解
[WriteGroup(typeof(ScaleComponentData))]
struct BigScaleTag : IComponentData { }
可以理解为把BigScaleTag放入一个集合中,这个集合有一个标识属性,这个标识类型是:ScaleComponentData
[WriteGroup(typeof(ScaleComponentData))]
struct SmallScaleTag : IComponentData { }
同理这里也是把组件SmallScaleTag放入一个集合中,该集合有一个标识属性,该属性的类型是:ScaleComponentData
上面的代码这样修饰后有什么作用?
可以根据不同的查询条件来对组件ScaleComponentData数据进行修改
2、查询解析
2.1、 如果一个Entity只有ScaleComponentData组件,那么下面的查询结果是什么?
foreach (var scaleComponent in SystemAPI.Query<RefRW<ScaleComponentData>>())
上面的代码能够查询到ScaleComponentData类型数据;和普通的查询没有任何区别;
2.2、在2.1的基础上,再给Entity加一个SmallScaleTag或者BigScaleTag组件,下面的查询结果是什么?
foreach (var scaleComponent in SystemAPI.Query<RefRW<ScaleComponentData>>())
上面的代码还是可以查询到结果的;和2.1一样;
但是加入了WriteGroup还是上面的结果就没啥意义了;
加入WriteGroup是为了在不同System之间,根据不同的条件对Entity的ScaleComponentData数据进行修改;该修改的数据作为其它系统的数据输入源;
所以,这个时候的代码应该是要修改为如下代码:
foreach (var scaleComponent in SystemAPI.Query<RefRW<ScaleComponentData>>().WithOptions(EntityQueryOptions.FilterWriteGroup))
意思是我想要查询ScaleComponentData组件,但前提是该Entity上没有和ScaleComponentData组件相关的WriteGroup属性;
更直白的说,如果entity上面同时具有ScaleComponentData和BigScaleTag组件:
看如下截图:
那么下面这段代码:
foreach (var scaleComponent in SystemAPI.Query<RefRW<ScaleComponentData>>().WithOptions(EntityQueryOptions.FilterWriteGroup))
是无法查询到结果的
因为它开启了过滤WriteGroup标签;也就是只要在Entiy上有目标类型ScaleComponentData的WriteGroup属性组件;它就查询不到结果。
如果不过滤这个属性,也就是2.1的代码,那它还是可以正常查询到结果的;
二、基本总结
WriteGroup属性标签比较困惑的地方是加上后的查询问题和在什么地方用;
就像上面说的,在不同的系统之间,需要根据不同的条件对一个组件数据进行修改,修改后的数据作为其它系统的数据源;这个时候是比较有用的;
因为各自ISystem之间的代码独立,相互不会影响,且达到解耦效果;
其中具有WriteGroup属性标签的查询,要根据自己添加的组件来进行查询;并且要注意原始数据,也就是原始数据是否要过滤属性标签,这里要做合适的处理,要不然得不偿失;