Skip to content

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-01
text
已用 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_scenequeue_spawn_scene,用法相同,适合在系统里使用。