2个版本
0.1.1 | 2023年10月16日 |
---|---|
0.1.0 | 2023年10月15日 |
#1583 in 异步
245KB
1K SLoC
bevy_async_system
此crate提供类似于UniTask
的功能,以异步等待游戏状态。
用法
所有示例均在此
。
once
once
用于仅运行系统一次。
除了简单的系统执行外,还用于更改状态和发送事件。
use bevy::prelude::*;
use bevy_async_system::prelude::*;
#[derive(Eq, PartialEq, Copy, Clone, Debug, Default, States, Hash)]
enum ExampleState {
#[default]
First,
Second,
}
#[derive(Resource, Eq, PartialEq, Default, Clone, Debug)]
struct Count(usize);
#[derive(Eq, PartialEq, Default, Clone, Debug)]
struct NonSendCount(usize);
fn setup(mut commands: Commands) {
commands.spawn_async(|schedules| async move {
schedules.add_system(Update, once::run(println_system)).await;
schedules.add_system(Update, once::set_state(ExampleState::Second)).await;
schedules.add_system(Update, once::init_resource::<Count>()).await;
schedules.add_system(Update, once::init_non_send_resource::<NonSendCount>()).await;
let count = schedules.add_system(Update, once::run(return_count)).await;
schedules.add_system(Update, once::insert_resource(count)).await;
schedules.add_system(Update, once::run(println_counts)).await;
schedules.add_system(Update, once::send(AppExit)).await;
});
}
fn println_system() {
println!("hello!");
}
fn return_count() -> Count {
Count(30)
}
fn println_counts(
count: Res<Count>,
non_send_count: NonSend<NonSendCount>
) {
println!("{count:?}");
println!("{non_send_count:?}");
}
wait
wait
使系统在满足特定条件之前保持运行。
例如,您可以轻松编写一个等待音乐播放结束的过程,如下所示。
use bevy::prelude::*;
use bevy_async_system::prelude::*;
fn setup_async_systems(mut commands: Commands) {
commands.spawn_async(|schedules| async move {
schedules.add_system(Update, once::run(play_audio)).await;
schedules.add_system(Update, wait::until(finished_audio)).await;
info!("***** Finished audio *****");
schedules.add_system(Update, once::send(AppExit)).await;
});
}
fn play_audio(
mut commands: Commands,
asset_server: Res<AssetServer>,
) {
commands.spawn(AudioBundle {
source: asset_server.load("audio/higurashi.ogg"),
settings: PlaybackSettings::ONCE,
});
}
fn finished_audio(
mut commands: Commands,
audio: Query<(Entity, &AudioSink)>,
) -> bool {
let Ok((entity, audio)) = audio.get_single() else { return false; };
if audio.empty() {
commands.entity(entity).despawn();
true
} else {
false
}
}
delay
您可以使用帧或定时器延迟任务。
use bevy::prelude::*;
use bevy_async_system::prelude::*;
fn setup(
mut commands: Commands,
mut settings: ResMut<FramepaceSettings>,
) {
settings.limiter = Limiter::from_framerate(30.);
commands.spawn_async(|schedules| async move {
println!("Wait 3 seconds...");
schedules.add_system(Update, delay::timer(Duration::from_secs(3))).await;
println!("Wait 90 frames...");
schedules.add_system(Update, delay::frames(90)).await;
});
}
repeat
repeat
用于多次运行系统。
use bevy::prelude::*;
use bevy_async_system::prelude::*;
fn setup(mut commands: Commands) {
commands.spawn_async(|schedules| async move {
schedules.add_system(Update, repeat::times(5, count_up)).await;
let handle = schedules.add_system(Update, repeat::forever(count_up));
schedules.add_system(Update, delay::timer(Duration::from_secs(3))).await;
// task and system cancel.
drop(handle);
println!("task canceled. Exit the application after 3 seconds.");
// Delay to make sure the system does not run.
schedules.add_system(Update, delay::timer(Duration::from_secs(3))).await;
println!("App exit");
schedules.add_system(Update, once::app_exit()).await;
});
}
fn count_up(mut count: Local<u32>) {
*count += 1;
println!("count = {}", *count);
}
兼容的Bevy版本
bevy_async_system | bevy |
---|---|
0.1 | 0.11 |
依赖项
~21–31MB
~477K SLoC