UnityECS学习03-Aspects
Aspect
首先回顾一下我们最开始的 HelloCube 代码。1
2
3
4
5foreach (var (transform, speed) in
SystemAPI.Query<RefRW<LocalTransform>, RefRO<RotationSpeed>>())
{
transform.ValueRW = transform.ValueRO.RotateY(speed.ValueRO.RadiansPerSecond * deltaTime);
}
此处就是通过 Query 一个一个查询组件,但是此时组件多了这个查询的条件就会特别长,此处就引入了 Aspect
Aspect
可以看成对 entity 一些组件的引用的 Wrapper
,也就是包装。Aspect
必须使用 readonly partial struct
声明接着继承 IAspect
。其中只能含有一下字段:
- 一个
entity
字段,用于存储其 ID。 RefRW<T>
和RefRO<T>
字段,其中 T 实现了IDataComponent
接口。EnabledRefRW
和EnabledRefRO
字段,用于访问实现了IEnableableComponent
接口的组件的启用状态。DynamicBuffer<T>
字段,用于访问实现了IBufferElementData
接口的缓冲区元素。ISharedComponent
字段,用于读取共享组件的值,并且这个访问是只读的。- 其他 Aspect 类型。
最终我们的代码就可以修改成这样:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33namespace HelloCube.Aspects
{
public partial struct RotationSystem : ISystem
{
[ ]
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<Execute.Aspects>();
}
[ ]
public void OnUpdate(ref SystemState state)
{
float deltaTime = SystemAPI.Time.DeltaTime;
foreach (var rotate in SystemAPI.Query<RotateAspect>())
{
rotate.Rotate(deltaTime);
}
}
}
readonly partial struct RotateAspect : IAspect
{
readonly RefRW<LocalTransform> m_Transform;
readonly RefRO<RotationSpeed> m_Speed;
public void Rotate(float deltaTime)
{
m_Transform.ValueRW = m_Transform.ValueRO.RotateY(m_Speed.ValueRO.RadiansPerSecond * deltaTime);
}
}
}
在 OnUpdate 中就可以使用我们定义的 Aspect 组件来查询。其会自动判断每个 entity 满足其中所有字段组件的要求,并自动为其填充数据。
readonly struct
此处再提一下 Aspect 组件当中定义的 readonly struct
。
其声明后主要有三个作用:
- 任何字段声明都必须具有
readonly
修饰符。 - 任何属性(包括自动实现的属性)都必须是只读的或仅 init。
- 除构造函数以外,其他实例成员都是
readonly
的。