该示例只要表达的是关闭和激活组件,之前的示例我们知道对于一个ECS组件需要继承IComponent接口,说明这个是一个组件,数组的话需要继承IBufferElementData接口,说明这个是一个数组元组组件,如果需要组件的激活控制,结构体需要继承IEnableableComponent
1.早baker的时候使用这个api设置组件的状态 SetComponentEnabled,这个是baker类中的一个api
public void SetComponentEnabled<T>(Entity entity, bool enabled) where T : struct, IEnableableComponent{if (_State.PrimaryEntity != entity){CheckValidAdditionalEntity(entity);}else{CheckComponentHasBeenAddedByThisBaker(entity, TypeManager.GetTypeIndex<T>());}_State.Ecb.SetComponentEnabled<T>(entity, enabled);}
可以看到源码中使用的是ecb设置的组件状态
示例中的代码是设置组件的读写状态,来改变旋转的效果
if (timer < 0){//EntityQueryOptions.IgnoreComponentEnabledState,这个查询忽略组件的状态,不管组件是激活还是不激活都会被找到foreach (EnabledRefRW<RotationSpeed> rotationSpeedEnabled inSystemAPI.Query<EnabledRefRW<RotationSpeed>>().WithOptions(EntityQueryOptions.IgnoreComponentEnabledState)){//设置组件的读写状态,只读状态和组件的状态有关,组件不激活状态只读的值应该是false激活状态值应该是truerotationSpeedEnabled.ValueRW = !rotationSpeedEnabled.ValueRO;}timer = interval;}// The query only matches entities whose RotationSpeed is enabled.foreach (var (transform, speed) inSystemAPI.Query<RefRW<LocalTransform>, RefRO<RotationSpeed>>()){transform.ValueRW = transform.ValueRO.RotateY(speed.ValueRO.RadiansPerSecond * deltaTime);}
容易忽略的点是EntityQueryOptions.IgnoreComponentEnabledState,这个查询选项忽略组件的状态,都可以查询到,就像的Mono中,物体不激活,GameObject.Find是查询不到的
读写引用的值的设置源码是:
public bool ValueRO => m_Ptr.GetBit();public unsafe bool ValueRW{get{return m_Ptr.GetBit();}set{bool bit = m_Ptr.GetBit();m_Ptr.SetBit(value);if (Hint.Likely(bit != value)){int value2 = math.select(1, -1, value);Interlocked.Add(ref UnsafeUtility.AsRef<int>(m_PtrChunkDisabledCount), value2);}}}
ValueRW的值和ValueRO的值有很大的关系也就是说,在修改组件的数据的时候,要看这个组件只读(RO)状态是不是true