Bevyのデフォルトプラグインを理解する
A refreshingly simple data-driven game engine built in Rust
Free and Open Source Forever!
スターターbevyプログラムは次のようになります.
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.run();
}
これはコア機能を追加し、ウィンドウを与えます.しかし、これらの「デフォルトプラグイン」は何をしているのでしょうか?我々は、ちょうどこのポストでそれを調査します.
プラグインのリストは以下の通りです.
ログプラグイン
This plugin is really simple, it will add an appropriate logger for your target (e.g. log to console when targeting wasm) and this will allow all logs to go to the right place.
It can be configured with a resource like this
app.insert_resource(bevy::log::LogSettings {
// filter logs lower than ERROR
level: bevy::log::Level::ERROR,
// also include INFO logs of module wgpu_core::instance
filter: "wgpu_core::instance=info".to_owned(),
});
You can also pass a log config via environment variable RUST_LOG
, this will override whatever settings where selected.
# equivalent
$ RUST_LOG="error,wgpu_core::instance=info" cargo run
コアプラグイン
The core plugin doesn't do anything too interesting. It will register some types, setup the time system, and setup the task pool.
One can use it to create timed systems, e.g. a system that does something every X amount of seconds:
#[derive(Component)]
struct Foo { pub timer: Timer }
// startup system to initialize timed component
fn my_setup(mut commands: Commands) {
commands
.spawn()
.insert(Foo {
// true to indicate a repeating timer
timer: Timer::from_seconds(5., true),
});
}
// system that does something based on timer
fn my_system(
mut query: Query<&mut Foo>,
time: Res<Time>,
) {
for mut item in query.iter_mut() {
// progress timers
item.timer.tick(time.delta());
if item.timer.finished() {
bevy::log::info!("this prints every 3 seconds!");
}
}
}
TransformPlugin
This plugin sets up a transform model that allows objects to have a position, described as a hierarchy of parent-children relationships, similar to other game engines.
Every entity with GlobalTransform
and Transform
components gets this functionality. The GlobalTransform
describes the entity's position globally, and is immutable by the user. The Transform
describes the entity position in respect to its "parent" (or the global reference if there isn't one); this is the component we can modify to change an entity's position.
Whenever a Transform
is updated, all its children get updated so their GlobalTransform
reflects their new position.
診断書
The diagnostics plugin allows us to record any metric of interest, bevy comes with two plugins EntityCountDiagnosticsPlugin
and FrameTimeDiagnosticsPlugin
that we can use to record some useful data, as well as LogDiagnosticsPlugin
, to log this diagnostics.
// ...
.add_plugin(bevy::diagnostic::FrameTimeDiagnosticsPlugin::default()
.add_plugin(bevy::diagnostic::LogDiagnosticPlugin::default())
インプットプラグイン
This plugin is very straight forward, we can read input events in our systems to react according to user actions.
As an example, here we are catching all mouse button input:
fn my_system(
mut events: EventReader<MouseButtonInput>,
) {
for event in events.iter() {
if event.state.is_pressed() {
bevy::log::info!("{:?} pressed!", event.button);
}
}
}
ウィンドウプラグイン
The window plugin is responsible for 2 things:
- Creating a window
- Managing window events
This means that just how we can react to mouse clicks, we can react to window events such as leaving or entering the window:
fn my_system(
mut events: EventReader<CursorEntered>,
) {
for event in events.iter() {
bevy::log::info!("cursor entered!");
}
}
We can also define some settings for the window creation:
.insert_resource(WindowDescriptor {
width: 400.,
height: 200.,
..Default::default()
})
// ...
プラグイン
This plugin allows us to load any asset and easily use them throughout our program. It features background IO which means our app won't lag from loading assets.
We can load an asset like this
fn load_something(
mut commands: Commands,
loader: Res<AssetServer>,
) {
// this won't block us until the resource is loaded !
let image: Handle<Image> = loader.load("image.png");
commands.insert_resource(MyAsset { image });
}
And request them like this
fn use_something(
assets: Res<MyAsset>,
images: Res<Assets<Image>>,
) {
// at this point the asset could be loaded or not yet
if let Some(loaded) = images.get(assets.image) {
// do something ...
}
}
The asset server provides features like filesystem watching, which enables hot reload of assets during development.
Asset loaders can be implemented for any kind of asset, images, text, anything.
There are still many more plugins to explore and how they interact with each other, I plan to make more posts about them and also about what using bevy's ECS looks like.
Reference
この問題について(Bevyのデフォルトプラグインを理解する), 我々は、より多くの情報をここで見つけました https://dev.to/viiik/understanding-bevys-default-plugins-53hfテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol