Bevy 引擎还处于一个非常早期的阶段,本文的内容很容易过时。若有商业开发需求 Godot 会更为合适。代码基于bevy v0.11.2
默认已通过 rustup 安装 rust 环境
在 Hello, ECS!(三)中还有一个重要概念我希望单独放一节中介绍。它是bevy_ecs
中 System 与 Component、行为与数据的中间桥梁:SystemParam。
SystemParam
在 Bevy 里 System 是什么?为什么一个函数就能成为 System?
Bevy 中 有个重要的 Trait 叫 IntoSystem。Bevy 为所有只包含特殊参数的 Function 实现了 IntoSystem Trait。
这些特殊参数可能是1:
- 用于访问 Resource 的
Res
/ResMut
- 用于查询 Entity 中具有满足条件的 Component 的
Query
- 用于创建/销毁 Entity、Component、Resource 的
Commands
- 用于发送/接收 Event 的
EventWriter
/EventReader
可以在这里找到所有的 SystemParam \
https://bevy-cheatbook.github.io/builtins.html#systemparams
下面是 Hello, ECS!(三) 中出现的其中一个 System
// ...
fn spawn_entities(mut commands: Commands, mut entity_counter: ResMut<EntityCounter>) {
if rand::thread_rng().gen_bool(0.6) {
let entity_id = commands.spawn(Age::default()).id();
println!(" spawning {entity_id:?}");
entity_counter.value += 1;
}
}
// ...
Exclusive System(专属系统)
正如 Hello, ECS!(四) 中提到
所有的 System 都会被包含在某个 Stage 中。每帧,Bevy 会按顺序处理各个 Stage。在各个 Stage,Bevy 的调度算法(scheduling algorithm)能使用多核处理器的性能,并发地运行各个 System 达到更好的性能。
但并发处理下,数据的读写成为了不可回避的问题。
众所周知,在多线程的操作下读写操作需要满足一下几个规则。
- 同一时刻,允许多个对同一数据的读取
- 同一时刻,不允许多个对同一数据的写入
- 同一时刻,不允许读取与写入同时进行
为了处理读写上的限制,在 SystemParam 的基础上往下延伸,Bevy 提供了一类特殊的 System - Exclusive System。
Exclusive System(专属系统)不会 System 并发执行,Exclusive System 可以不受限制地访问 ECS World 中的数据。
但由于 Exclusive System 无法并发执行,所以 Exclusive System 也无法被分配到多个线程中执行,所以 Exclusive System 的执行效率也会受到影响。
当一个 System 函数包含了&mut World
参数(也就是对 World 的可变引用)时,这个 System 就会被 Bevy 认为是 Exclusive System。(同样的,这个操作是在编译时 Bevy 通过 IntoSystem Trait 实现的,可谓相当节能)
部份参数在 Hello, ECS!(三) 中有体现 ↩︎