问题描述
在一个Bevy项目中,其中包含以下名为my_scene.scn
的场景文件:
[
(
entity: 0,components: [
{
"type": "Transform","map": {
"translation": {
"type": "Vec3","value": (150.0,200.0,0.0),},"rotation": {
"type": "Quat","value": (0.0,0.0,1.0),"scale": {
"type": "Vec3","value": (0.75,0.75,]
)
]
此源代码位于this official Bevy example之后:
use bevy::prelude::*;
fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_startup_system(load_scene_system.system())
.run();
}
fn load_scene_system(asset_server: Res<AssetServer>,mut scene_spawner: ResMut<Scenespawner>) {
let scene_handle: Handle<Scene> = asset_server.load("my_scene.scn");
scene_spawner.spawn_dynamic(scene_handle);
// ^ How to add components to entities created here ?
asset_server.watch_for_changes().unwrap();
}
我想向该实体0添加其他组件,例如SpriteComponents
。我该如何实现?
解决方法
这是我想出的解决方案。这个想法是存储一个组件 包含创建更动态组件的信息。
例如,要动态加载场景文件中引用的子画面图像,我们
可以定义一个SpriteLoader
组件,然后添加一个系统,该系统将用我们想要的组件替换该加载器组件。
use bevy::prelude::*;
fn main() {
App::build()
.add_plugins(DefaultPlugins)
.register_component::<SpriteLoader>()
.add_startup_system(load_scene_system.system())
.add_system(load_sprite_system.system())
.run();
}
fn load_scene_system(asset_server: Res<AssetServer>,mut scene_spawner: ResMut<SceneSpawner>) {
let scene_handle: Handle<DynamicScene> = asset_server.load("my_scene.scn");
scene_spawner.spawn_dynamic(scene_handle);
asset_server.watch_for_changes().unwrap();
}
/// Component indicating that a sprite will be loaded for the entity.
#[derive(Properties,Default)]
pub struct SpriteLoader {
/// Path of the sprite to load
pub path: String
}
/// Replaces the `SpritLoader` component with the corresponding `SpriteComponents`.
pub fn load_sprite_system(
mut commands: Commands,asset_server: Res<AssetServer>,mut materials: ResMut<Assets<ColorMaterial>>,query: Query<(Entity,Added<SpriteLoader>)>,) {
for (entity,sprite_loader) in query.iter() {
commands.remove_one::<SpriteLoader>(entity);
let path = PathBuf::from(sprite_loader.path.clone());
commands.insert(
entity,SpriteComponents {
material: materials.add(asset_server.load(path).into()),..SpriteComponents::default()
},);
}
}
在此处,将SpriteLoader
添加到实体后,load_sprite_system
系统将删除它并插入一个
改为SpriteComponents
。根据{{3}},这
将替换之前的SpriteComponents
。
对应的场景文件是:
[
(
entity: 0,components: [
{
"type": "SpriteLoader","map": {
"path": "my_sprite.png",},]
)
]