用途
该技能用于 Bevy 0.20 中处理两类任务:从磁盘加载资源,以及把场景描述生成为实体。当内容来自磁盘,或需要用场景描述生成实体时使用。AssetServer 负责加载文件,bsn! 宏描述一个 Scene,再由 spawn_scene 或 queue_spawn_scene 将其转为实体。
主要能力
资源加载(Assets)
- AssetServer 是从磁盘加载的资源(resource)。
- AssetServer::load 返回一个 Handle,只要强句柄仍存在就不会重新加载。
- 已加载的数据存放在 Assets<T> 中。
- AssetServer::is_loaded_with_dependencies 在资源及其依赖就绪时返回 true。
- LoadState 是状态类型。
句柄(Handles)
- 强句柄采用引用计数。丢弃最后一个强句柄会移除该资源。
- 弱句柄不会保持资源存活。
- Assets::add 插入程序化生成的资源,且不做去重。
热重载
- file_watcher Cargo 特性,以及 AssetPlugin 的 watch_for_changes_override 字段,是资源索引页中列出的开关。
场景(Scenes)
- bevy::scene 描述一个 Scene(实体、组件、子级、资源),用 bsn! 宏构建。
- World::spawn_scene 与 Commands::spawn_scene 立即生成,若资源依赖未加载则报错。
- World::queue_spawn_scene 与 Commands::queue_spawn_scene 会等待,然后在 Update 与 PostUpdate 之间的 SpawnScene 调度中生成。
- 场景中的层级:在 bsn! 内使用 Children [ ... ]。用 -- 分隔同级实体。#Name 在该宏作用域内赋予一个 Name。
使用方式
资源选择对照:
- 加载文件:AssetServer::load 返回 Handle。
- 等待就绪:在状态切换前使用 is_loaded_with_dependencies。
- 立即生成场景:仅在依赖已加载后使用 spawn_scene。
- 就绪后生成:使用 queue_spawn_scene(SpawnScene 位于 Update 与 PostUpdate 之间)。
- 场景中的子级:在 bsn! 内使用 Children。
- 更改单个实体的网格:替换存储它的组件上的 Handle。
依赖与示例代码:
[dependencies]
bevy = { version = "0.20", features = ["file_watcher"] }
#[derive(Resource)]
struct PropMesh(Handle<Mesh>);
fn begin_load(mut commands: Commands, assets: Res<AssetServer>) {
let handle: Handle<Mesh> = assets.load("models/crate.glb#Mesh0/Primitive0");
commands.insert_resource(PropMesh(handle));
}
fn mesh_is_ready(assets: Res<AssetServer>, mesh: Option<Res<PropMesh>>) -> bool {
match mesh {
Some(mesh) => assets.is_loaded_with_dependencies(&mesh.0),
None => false,
}
}
fn store_generated_material(
mut materials: ResMut<Assets<StandardMaterial>>,
mut commands: Commands,
) {
let handle = materials.add(StandardMaterial {
base_color: Color::srgb(0.8, 0.8, 0.82),
..default()
});
commands.insert_resource(GeneratedMaterial(handle));
}
#[derive(Resource)]
struct GeneratedMaterial(Handle<StandardMaterial>);
#[derive(Component, Default, Clone)]
struct CrateProp;
#[derive(Component, Default, Clone)]
struct Lid;
#[derive(Component, Default, Clone)]
struct LevelRoot;
fn spawn_crate(mut commands: Commands) {
commands.spawn_scene(bsn! {
#SupplyCrate
CrateProp
Children [
Lid
]
});
}
fn queue_level(mut commands: Commands) {
commands.queue_spawn_scene(bsn! {
:"levels/yard.bsn"
LevelRoot
});
}
fn replace_level(mut commands: Commands, roots: Query<Entity, With<LevelRoot>>) {
for entity in &roots {
commands.entity(entity).despawn();
}
commands.queue_spawn_scene(bsn! {
LevelRoot
});
}
适用场景
- 内容来自磁盘,需要加载文件并等待就绪后再切换状态。
- 需要用场景描述生成实体,并控制立即生成还是就绪后生成。
- 需要在场景中表达父子层级。
- 需要替换关卡:先 despawn 其根实体释放上一关,再 queue 下一个场景。
- 需要注册自定义 AssetLoader(在该 loader 类型存在后,用 App::register_asset_loader 注册一次)。
限制与注意事项
- 目标版本为 Bevy 0.20+。
- 磁盘上的 .bsn 文件仍领先于已发布的场景 API,请用 bsn! 编写场景。
- 不要在文档 URL 中固定 /0.20.0/。
- 不要从两个无序系统可变查询同一组件;调度器会并行运行系统,除非用 .chain() 排序。
- 不要在此虚构物理、导航、网络或 XR crate;本技能只命名有文档的 Bevy crate 与模块。
- 不要使用其他引擎的打包场景或资源加载器类型;就绪判断是 is_loaded_with_dependencies,生成是 spawn_scene 或 queue_spawn_scene。
- 不要使用本文件未打开的场景格式,也不要使用第三方场景 crate。
- 遇到文档集之外的 API,先查阅官方文档,不要编造 crate 或 API。
相关技能
- 前置:bevy-master(状态归属)、bevy-project-foundations(Cargo 特性,含资源监视标志)、bevy-state-machines(资源页指向应用状态用于加载门控)。
- 互补:bevy-audio-systems(通过 AssetServer 加载音频片段)、bevy-save-load(玩家存档,与场景生成分离)。
- 下游/消费者:bevy-camera-systems(场景可能生成的相机实体)。
- 主路由:bevy-master。