Asset 系统
《侠客行》杀青那天,老雷在庆功宴上宣布开新戏:《长风渡》。可第二天一早,剧组就发现一个尴尬的事实——青蝉影视城拍了一整部戏,库房却是空的。上一章片场里所有看得见的东西,侠客、白马、马克点,全是代码里现编的色块:Sprite::from_color 一句话,凭空变出一块布。真正的美术素材——画好的图片、录好的音频、做好的模型、写好的剧本——一件都还没进过门。
这一章拆 Bevy 的 Asset(资产——从外部文件加载进来、不属于任何一个实体的数据:图片、音频、网格、材质、字体,乃至你自己定义的格式)系统。它解决三个问题:素材文件怎么进入运行中的游戏;同一份素材怎么被多处共享而不复制多份;以及最要紧的——磁盘很慢,游戏很快,两者怎么互不耽误。
具体路线:
- 第一件道具——
AssetServer与assets/目录约定;亲眼看见“load立刻返回,货稍后才到”; - Handle(句柄)——那张轻飘飘的提货单:克隆、比较、引用计数,以及货架
Assets<T>; - 到货了吗——查询
LoadState、收听AssetEvent广播,外加一次“库里没这件货”的真实报错; - 开机进度条——整本戏的家当一起装货,配上第 10 章的 States,全齐才开机;
- 剧本也是资产——
#[derive(Asset)]加自定义AssetLoader,教库房认识我们自己发明的.script文本格式; - 现场改词——
file_watcher热重载:编剧存盘,台上立刻换词,连图片都能运行中偷天换日; - 库房的细则——加载设置与
.meta档案、嵌进可执行文件的 embedded 资产、发布期的 asset processing 概述。
这些类型住在 bevy_asset 这个 crate 里;图片资产的具体类型 Image 则来自 bevy_image(它的渲染细节是下一章的事)。
本章的舞台还在青蝉影视城,只是镜头转向幕后:道具师老顾掌管道具库,跑腿小哥阿迅负责进货,编剧秋白随时改稿,导演老雷只关心一件事——什么时候能开机。配套 crate 是 code/ch14-assets,它的 Cargo.toml 比前几章多两样东西,先交个底:
toml
[package]
name = "ch14-assets"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
[dependencies]
# file_watcher 让 AssetServer 监视磁盘文件改动——热重载(14.6 节)的开关。
# 这是开发期 feature,发布构建不应该带它
bevy = { workspace = true, features = ["file_watcher"] }
# 自定义 AssetLoader(14.5 节)的错误类型用 thiserror 派生
thiserror = "2"file_watcher 要到 14.6 节才登场,thiserror 在 14.5 节派上用场。assets/ 目录里那些像素画与大幅幕布由 scripts/make_ch14_assets.py 一键生成,仓库里已经备好,不用自己画。