youtu.be今回の目的は、システムの実行順をコントロールする方法として、.before, .after, .chain, systemsetを実践することです。
今回は、動画のコードは分かりにくいので、system a system b system cという関数を作り、それの実行結果について考察を行う。
まずは以下の様なコードをビルドして、順番を確かめた。
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_systems(Startup, (system_a, system_b, system_c))
.run();
}
fn system_a() {
println!("System A is running");
}
fn system_b() {
println!("System B is running");
}
fn system_c() {
println!("System C is running");
}

この実行結果の場合、ビルドする度に、Systemの実行順が変わっていることが分かる。
つまり、bevyは並列処理をするため、五月雨に実行していて順番が変わるのである。
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_systems(Startup, system_c.before(system_a))
.add_systems(Startup, system_a.after(system_b))
.add_systems(Startup, system_b.after(system_c))
.run();
}
fn system_a() {
println!("System A is running");
}
fn system_b() {
println!("System B is running");
}
fn system_c() {
println!("System C is running");
}

上の3つのシステムの順番は3回実行しても変わらなかった。
今回は、3つの条件を与えて、順番を統制した。はじめは、二つしか条件を与えていなかったので、完全に忘れていた。
次に、

use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_systems(Startup, (system_a, system_b, system_c).chain())
.run();
}
fn system_a() {
println!("System A is running");
}
fn system_b() {
println!("System B is running");
}
fn system_c() {
println!("System C is running");
}
このように、chain()を使うことで、一発で順番を完全に制御できる。
use bevy::prelude::*;
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub struct Systemset1;
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub struct Systemset2;
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.configure_sets(Startup, Systemset1.before(Systemset2))
.add_systems(Startup, system_a.in_set(Systemset1))
.add_systems(Startup, system_b.in_set(Systemset1))
.add_systems(Startup, system_c.in_set(Systemset2))
.run();
}
fn system_a() {
println!("System A is running");
}
fn system_b() {
println!("System B is running");
}
fn system_c() {
println!("System C is running");
}
そして、もう一つの方法として、SystemSetも使ってみた。
今回は、
SystemSetは
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub struct Systemset1;
このように宣言し、導入するときは、
.configure_sets(Startup, Systemset1.before(Systemset2))
このように宣言する。
これは、Systemset1を、Systemset2の前に実行するという意味である。
さらに、既存のシステムをSystemSetに入れたいときは、.in_set()を用いる。
これにより、システムをシステムセットに所属させることが出来る。
そして、実行結果は必ずABCの順番になった。つまり、Systemset1にコードの順番通りに記録され、それがSystemset2の前に実行されたという事になる。
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.configure_sets(Startup, Systemset1.before(Systemset2))
.add_systems(Startup, system_b.in_set(Systemset1))
.add_systems(Startup, system_a.in_set(Systemset1))
.add_systems(Startup, system_c.in_set(Systemset2))
.run();
}
また、このようにsystembの、.in_setを先に宣言すると、
実行結果は必ずBACの順になる。.insetは並列処理はされない。
SystemSetは、enum型でも宣言できる。
use bevy::prelude::*;
// #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
// pub struct Systemset1;
// #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
// pub struct Systemset2;
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
FunctionAB,
FunctionC,
}
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.configure_sets(
Startup,
SystemSetABC::FunctionAB.before(SystemSetABC::FunctionC),
)
.add_systems(Startup, system_a.in_set(SystemSetABC::FunctionAB))
.add_systems(Startup, system_b.in_set(SystemSetABC::FunctionAB))
.add_systems(Startup, system_c.in_set(SystemSetABC::FunctionC))
.run();
}
fn system_a() {
println!("System A is running");
}
fn system_b() {
println!("System B is running");
}
fn system_c() {
println!("System C is running");
}
これの実行結果は、必ずABCになる。
まとめると、今回は
二つの実行順を制御したい場合は.before(), .after()を使う。
.chain()は順番を完全に制御できる。
大きなプロジェクトで実行順を把握するには、SystemSetを使う。その為には、.configure_set()と.in_set()が必要である。