BSN 入门
BSN(Bevy Scene Notation)是 Bevy 0.19 引入的声明式场景描述系统。用 bsn! 宏代替逐个 commands.spawn(),像写 HTML 一样描述实体树:组件、子实体、观察者、资产引用——一行一个,组合复用。
第一个 bsn!
bsn! 宏生成一个 Scene,交给 World::spawn_scene 即可生成实体:
rust
fn setup(world: &mut World) {
world.spawn_scene(bsn! {
#Player
Health(100)
Score(0)
}).unwrap();
println!("已用 bsn! 生成实体");
}Listing 32-1:用 bsn! 生成实体
运行:
console
cargo run -p ch32-scenes --example listing-32-01text
已用 bsn! 生成实体#Player 给实体加上 Name("Player") 组件,Health(100) 和 Score(0) 是普通组件。spawn_scene 返回 Result<EntityWorldMut, SpawnSceneError>,成功时拿到生成的实体。
组件要求
在 bsn! 里使用的组件必须满足以下条件之一:
Default + Clone:简单组件的首选,适用于所有字段都有合理默认值的类型FromTemplate:需要运行时上下文的组件(如Handle<T>字段需要AssetServer解析路径)
rust
// 简单组件:derive Default + Clone
#[derive(Component, Default, Clone)]
struct Health(i32);
// 需要资产的组件:derive FromTemplate
#[derive(Component, FromTemplate)]
struct Icon {
image: Handle<Image>,
tint: Color,
}两种方式都支持补丁(Patching):bsn! 里只写需要覆盖的字段,其余保留默认值或来自组合场景的值。
基本语法速查
| 写法 | 含义 |
|---|---|
CompA | 单元组件或默认值组件 |
CompA(val) | 元组组件,指定部分字段 |
CompA { field: val } | 结构体组件,指定部分字段 |
#Name | 添加 Name("Name") 组件,同时注册为可引用名称 |
Children [scene1, scene2] | 子实体列表 |
on(|ev: On<E>| { ... }) | 附加实体观察者 |
{expr} | 动态表达式,运行时求值 |
spawn_scene 与 queue_spawn_scene
两种生成方式:
| 方法 | 行为 | 适用场景 |
|---|---|---|
spawn_scene | 立即解析并生成 | 无资产依赖,或资产已加载 |
queue_spawn_scene | 注册依赖,等资产加载后生成 | 场景引用了未加载的资产(如图片、字体) |
Commands 也有对应的 spawn_scene 和 queue_spawn_scene,用法相同,适合在系统里使用。