事件让我们可以在System之间通信,我们可以在一个系统中发送事件,然后在另一个系统中接收事件以触发我们的游戏逻辑。
添加事件
我们先定义我们的事件:
rust
#[derive(Event)]
struct PlayerDetected(i32);
事件只需要derive(Event)
即可,同时事件也是一个普通的结构体,它可以包含数据,也可以不包含。
在我们声明了事件类型之后,我们需要添加到App
中:
rust
// other code...
App::new().add_event::<PlayerDetected>()
// other code...
需确保 add_event::<PlayerDetected>()
在注册相关系统之前调用,否则事件无法被识别。
此时,我们就可以在我们的系统中使用事件了。
发送事件
rust
fn send_player_detected(mut events: EventWriter<PlayerDetected>) {
events.send(PlayerDetected(1));
}
发送事件需要定义一个可变的EventWriter
,泛型参数填入我们的事件类型,当我们需要触发事件的时候,调用EventWriter.send
发送事件。
读取事件
rust
fn on_player_detected(mut events: EventReader<PlayerDetected>) {
events
.read()
.for_each(|ev| info!("detected player: {}", ev.0));
}
读取事件稍显特殊,使用EventReader
读取事件,调用函数read()
会返回一个读取事件的迭代器,如果有事件触发,会进入到for_each
中,当然,使用for
循环也是一样的。
注册系统
别忘了,把两个系统添加到我们的App
中:
rust
// other code...
.add_systems(
Update,
send_player_detected.run_if(input_just_pressed(KeyCode::Space)),
)
.add_systems(Update, on_player_detected)
// other code...
注意这里我们在触发send_player_detected
系统的时候,判定了是否按下空格键。
此时,当我们按下空格键的时候,便会触发PlayerDetected
事件。
总结
总体来讲,Bevy 的事件使用起来是比较简单的。事件是将发生的事情 与应该发生的事情分离的主要方式,通过事件能够让我们的游戏更具可扩展性。