bevy-custom-assets について
Bevy 0.19でカスタムアセットローダーを実装する開発者向けのスキルです。非同期ファイルアクセス、依存アセットの読み込み、API変更点を扱います。
主な機能
- 01カスタムアセットローダーの実装
- 02非同期読み込みとランダムアクセス
- 03LoadContext経由の依存読み込み
- 04Bevy 0.19のAPI変更への対応
活用シーン
- 01独自のバイナリ形式やテキスト形式の読み込み
- 02参照アセットを扱うレベルローダーの作成
- 03旧式のネスト読み込みコードの移行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ chrisgliddon/ bevy-skills --skill bevy-custom-assetsインストール後、Claude Code で/bevy-custom-assetsを入力して読み込まれたか確認します。
詳細
Bevy 0.19 — カスタムアセットローダー
このスキルを使う場面
- 独自のバイナリ形式またはテキスト形式(独自のゲームデータ、サイドカーレ設定など)を読み込む場合。
- 他のアセットに依存するアセットを生成する場合(参照先のテクスチャを読み込むレベルローダーなど)。
LoadContext::loader()または古いNestedLoaderからload_builder()/NestedLoadBuilderに移行する場合。- 基になるファイルへの非同期アクセス(
reader.read_to_end、reader.seekable())が必要な場合。 - コンパイラーエラー:"
MyLoader: TypePathis not implemented" — 0.18 ではローダーにTypePathが必須になりました。
標準的なパターン
use bevy::asset::io::Reader;
use bevy::asset::{Asset, AssetApp, AssetLoader, LoadContext};
use bevy::prelude::*;
use bevy::reflect::TypePath;
use serde::Deserialize;
use thiserror::Error;
#[derive(Asset, TypePath, Debug, Deserialize)]
pub struct LevelDef {
pub name: String,
pub gravity: f32,
pub thumbnail: String, // path to a referenced texture asset
}
#[derive(TypePath)] // 0.18: required on the loader itself.
pub struct LevelLoader;
#[derive(Debug, Error)]
pub enum LevelLoaderError {
#[error("io: {0}")]
Io(#[from] std::io::Error),
#[error("parse: {0}")]
Parse(#[from] ron::error::SpannedError),
}
impl AssetLoader for LevelLoader {
type Asset = LevelDef;
type Settings = ();
type Error = LevelLoaderError;
async fn load(
&self,
reader: &mut dyn Reader,
_settings: &Self::Settings,
load_context: &mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
// Pull the whole file. For very large files prefer `seekable()`.
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let level: LevelDef = ron::de::from_bytes(&bytes)?;
// Pull in a referenced asset so it loads alongside this one.
// The resulting handle ends up tracked as a dependency.
let _: Handle<Image> = load_context.load_builder().load(level.thumbnail.clone());
Ok(level)
}
fn extensions(&self) -> &[&str] {
&["level.ron"]
}
}
pub struct LevelLoaderPlugin;
impl Plugin for LevelLoaderPlugin {
fn build(&self, app: &mut App) {
app.init_asset::<LevelDef>()
.register_asset_loader(LevelLoader);
}
}
ランダムアクセス用に Reader を要求する
// Bevy 0.19 requires Reader implementations to expose `seekable()`.
# use bevy::asset::io::Reader;
# async fn _example(reader: &mut dyn Reader) -> std::io::Result<()> {
match reader.seekable() {
Ok(seekable) => {
// SeekableReader supports `seek(SeekFrom::Start(n))`, `seek(SeekFrom::End(-n))`, etc.
let _ = seekable;
}
Err(_) => {
// Source isn't seekable (e.g. HTTP backend). Fall back to streaming.
}
}
# Ok(())
# }
Bevy 0.19 の注意点
- ローダー構造体には
#[derive(TypePath)]が必須です(アセットだけでなく、ローダーにも必要です)。0.18 ではローダーをリフレクション可能にするため、これが必須になりました。指定しないと、"MyLoader: TypePathis not implemented" というエラーが発生します。 LoadContext::path()が返すのはAssetPathであり、&Pathではありません。プラットフォームのパスを取得するには、AssetPathの.path()を使います:ctx.path().path()。LoadContext::asset_bytes()は削除されました。load非同期関数内でlet mut bytes = Vec::new(); reader.read_to_end(&mut bytes).await?;を使うか、ランダムアクセスにはreader.seekable()を使います。- 依存関係は
LoadContextを通じて読み込む必要があります。 ローダー内でasset_server.load(...)を呼び出しても、生成中のアセットの依存関係として結果は登録されません。AssetEvent::LoadedWithDependenciesが正しく発火するように、load_context.load_builder().load(...)(または簡便メソッドのload(...))を使います。 LoadContext::loader()は 0.19 で置き換えられました。load_context.load_builder()を使います。即時ロードはload_valueに、動的ロードはload_erasedに、型が不明なロードはビルダー操作のload_untypedに置き換えられました。- 独自の
Reader実装では、0.19 からseekable()の定義が必須です。 型がAsyncSeekを実装している場合に限りOk(self)を返し、それ以外の場合はErr(ReaderNotSeekableError)を返します。 AssetLoaderは非同期ですが、その内部でtokio::spawnは使用できません。エグゼキューターは Tokio ではなく Bevy のものです。計算負荷の高い処理にはbevy::tasks::futures_liteまたはbevy::tasks::AsyncComputeTaskPoolを使います。- アセット型には
#[derive(Asset)]が必須で、TypePathと組み合わせて使います。.metaファイルに対応させるには、アセットのSettings型がDefault + Serialize + DeserializeOwned + Send + Sync + 'staticを満たす必要があります。 - 拡張子はサフィックス全体で照合されます。
"level.ron"はfoo.level.ronに一致しますが、foo.ronには一致しません。汎用的な RON と区別する場合に便利です。
関連項目
bevy-assets— 読み込み済みのHandle<MyAsset>の使用方法。bevy-voxel-data— RON 駆動のアセットパターン。bevy-migration-0-17-to-0-18—LoadContext::asset_bytesの削除。bevy-migration-0-18-to-0-19— ネストされたロードビルダーと Reader の変更。
コメント
Markdown 対応