diff --git a/bevy_asset_loader/Cargo.toml b/bevy_asset_loader/Cargo.toml index 35a9aa6..7d406d1 100644 --- a/bevy_asset_loader/Cargo.toml +++ b/bevy_asset_loader/Cargo.toml @@ -25,7 +25,7 @@ bevy_asset_loader_derive = { version = "=0.17.0", path = "../bevy_asset_loader_d anyhow = "1" path-slash = "0.2" -bevy_common_assets = { version = "0.7.0", features = ["ron"], optional = true } +bevy_common_assets = { path = "../../bevy_common_assets", version = "0.7.0", features = ["ron"], optional = true } serde = { version = "1", optional = true } iyes_progress = { version = "0.9.0", optional = true } @@ -33,7 +33,7 @@ iyes_progress = { version = "0.9.0", optional = true } bevy = { version = "0.11", features = ["vorbis"] } anyhow = "1" iyes_progress = { version = "0.9.0" } -bevy_common_assets = { version = "0.7.0", features = ["ron"] } +bevy_common_assets = { path = "../../bevy_common_assets", version = "0.7.0", features = ["ron"] } serde = { version = "1" } trybuild = { version = "1.0" } @@ -95,3 +95,4 @@ required-features = ["2d", "3d", "standard_dynamic_assets"] [[example]] name = "custom_dynamic_assets" path = "examples/custom_dynamic_assets.rs" +required-features = ["2d", "standard_dynamic_assets"] diff --git a/bevy_asset_loader/assets/custom.my-assets.ron b/bevy_asset_loader/assets/custom.my-assets.ron index bd2f712..8e247dc 100644 --- a/bevy_asset_loader/assets/custom.my-assets.ron +++ b/bevy_asset_loader/assets/custom.my-assets.ron @@ -11,6 +11,14 @@ bottom_layer: "images/tree.png", top_layer: "images/player.png", ), + "tree": File(path: "images/tree.png"), + "images": [ + CombinedImage ( + bottom_layer: "images/tree.png", + top_layer: "images/player.png", + ), + File(path: "images/player.png") + ], "cube": Cube ( size: 1.3, ), diff --git a/bevy_asset_loader/examples/custom_dynamic_assets.rs b/bevy_asset_loader/examples/custom_dynamic_assets.rs index b736d28..62cf439 100644 --- a/bevy_asset_loader/examples/custom_dynamic_assets.rs +++ b/bevy_asset_loader/examples/custom_dynamic_assets.rs @@ -1,3 +1,4 @@ +use anyhow::Error; use bevy::core_pipeline::clear_color::ClearColorConfig; use bevy::prelude::*; use bevy::reflect::{TypePath, TypeUuid}; @@ -10,9 +11,10 @@ fn main() { .insert_resource(Msaa::Off) .add_plugins(( DefaultPlugins, + // We need to make sure that our dynamic asset collections can be loaded from the asset file + // You could also use other file formats than `ron` here RonAssetPlugin::::new(&["my-assets.ron"]), )) - // We need to make sure that our dynamic asset collections can be loaded from the asset file .add_state::() .add_loading_state( LoadingState::new(MyStates::AssetLoading).continue_to_state(MyStates::Next), @@ -72,12 +74,26 @@ fn render_stuff(mut commands: Commands, assets: Res) { transform: Transform::from_xyz(0.0, 200.0, 0.0), ..default() }); + // The two images that are part of the collection in `custom.my-assets.ron` + // The first is the combined image, the second is the player sprite + commands.spawn(SpriteBundle { + texture: assets.images[0].clone(), + transform: Transform::from_xyz(-200.0, 200.0, 0.0), + ..default() + }); + commands.spawn(SpriteBundle { + texture: assets.images[1].clone(), + transform: Transform::from_xyz(200.0, 200.0, 0.0), + ..default() + }); } #[derive(AssetCollection, Resource)] struct MyAssets { #[asset(key = "combined_image")] combined_image: Handle, + #[asset(key = "images", collection(typed))] + images: Vec>, #[asset(key = "tree_standard_material")] tree_standard_material: Handle, #[asset(key = "player_standard_material")] @@ -99,6 +115,9 @@ enum CustomDynamicAsset { Cube { size: f32, }, + // This allows us to use all the standard dynamic assets in the same files as our custom ones + #[serde(untagged)] + Standard(StandardDynamicAsset), } impl DynamicAsset for CustomDynamicAsset { @@ -118,12 +137,16 @@ impl DynamicAsset for CustomDynamicAsset { base_color_texture, .. } => vec![asset_server.load_untyped(base_color_texture)], CustomDynamicAsset::Cube { .. } => vec![], + CustomDynamicAsset::Standard(standard) => standard.load(asset_server), } } // This method is called when all asset handles returned from `load` are done loading. // The handles that you return, should also be loaded. fn build(&self, world: &mut World) -> Result { + if let CustomDynamicAsset::Standard(standard) = self { + return standard.build(world); + } let cell = world.cell(); let asset_server = cell .get_resource::() @@ -192,13 +215,56 @@ impl DynamicAsset for CustomDynamicAsset { Ok(DynamicAssetType::Single(handle)) } + CustomDynamicAsset::Standard(_) => unreachable!("standard assets are already handled"), + } + } +} + +#[derive(serde::Deserialize, Debug, Clone)] +#[serde(untagged)] +enum CustomDynamicAssets { + Single(CustomDynamicAsset), + Collection(Vec), +} + +impl DynamicAsset for CustomDynamicAssets { + fn load(&self, asset_server: &AssetServer) -> Vec { + match self { + CustomDynamicAssets::Single(single) => single.load(asset_server), + CustomDynamicAssets::Collection(collection) => collection + .iter() + .flat_map(|single| single.load(asset_server)) + .collect(), + } + } + + fn build(&self, world: &mut World) -> Result { + match self { + CustomDynamicAssets::Single(single) => single.build(world), + CustomDynamicAssets::Collection(collection) => { + let results: Result, Error> = collection + .iter() + .map(|single| single.build(world)) + .collect(); + results.map(|mut dynamic_assets| { + DynamicAssetType::Collection( + dynamic_assets + .drain(..) + .flat_map(|asset| match asset { + DynamicAssetType::Single(single) => vec![single], + DynamicAssetType::Collection(collection) => collection, + }) + .collect(), + ) + }) + } } } } #[derive(serde::Deserialize, TypeUuid, TypePath)] #[uuid = "18dc82eb-d5f5-4d72-b0c4-e2b234367c35"] -pub struct CustomDynamicAssetCollection(HashMap); +pub struct CustomDynamicAssetCollection(HashMap); impl DynamicAssetCollection for CustomDynamicAssetCollection { fn register(&self, dynamic_assets: &mut DynamicAssets) {