Latest commit 85dac0c
事件
相关的官方文档:[event]
在系统间发送数据:
EventWriter<T>:发送事件EventReader<T>:接收事件
每个Reader独立地追踪已读取的事件,因此可以处理来自多个系统的事件。
#![allow(unused)] fn main() { struct LevelUpEvent(Entity); fn player_level_up( mut ev_levelup: EventWriter<LevelUpEvent>, query: Query<(Entity, &PlayerXp)>, ) { for (entity, xp) in query.iter() { if xp.0 > 1000 { ev_levelup.send(LevelUpEvent(entity)); } } } fn debug_levelups( mut ev_levelup: EventReader<LevelUpEvent>, ) { for ev in ev_levelup.iter() { eprintln!("Entity {:?} level up!", ev.0); } } }
自定义事件要先在 [App Builder] 中注册:
fn main() { App::new() // ... .add_event::<LevelUpEvent>() .add_system(player_level_up) .add_system(debug_levelups) // ... .run(); }
事件应该是首选的数据流工具,因为事件可以从任何系统发送,并由多个系统接收,用途广泛。
隐藏的陷阱
注意 [Avoiding Frame Delays / 1-frame-lag]。如果Bevy在发送事件的系统之前先运行了接收事件的系统,就会出现这种情况。接收事件的系统只能在下一帧更新时接收事件。如果要在发送事件的同一帧立即接收事件,可以用 [System Order of Execution]。
事件不能持久。事件的储存时间是当前帧到下一帧结束前,之后就会丢失。如果某个处理事件的系统不是每帧运行,就会错过一些事件。这种设计好处是不用担心内存浪费在未处理的事件上。
如果希望事件能持久,可以[手动控制何时清除事件](忘记清除事件会浪费内存,甚至导致内存泄露)。