From 836fad498207574118cbc1f279ab781ae66f7dce Mon Sep 17 00:00:00 2001 From: Niklas Eicker Date: Mon, 30 Dec 2024 00:38:30 +0100 Subject: [PATCH] asset saver example --- .gitignore | 2 + CHANGELOG.md | 2 + Cargo.toml | 5 ++ README.md | 5 ++ examples/asset_savers/asset_savers.rs | 83 ++++++++++++++++++ examples/asset_savers/assets/tree.png | Bin 0 -> 830 bytes examples/asset_savers/assets/tree.png.meta | 12 +++ examples/asset_savers/assets/trees.level | 34 +++++++ examples/asset_savers/assets/trees.level.meta | 11 +++ 9 files changed, 154 insertions(+) create mode 100644 examples/asset_savers/asset_savers.rs create mode 100644 examples/asset_savers/assets/tree.png create mode 100644 examples/asset_savers/assets/tree.png.meta create mode 100644 examples/asset_savers/assets/trees.level create mode 100644 examples/asset_savers/assets/trees.level.meta diff --git a/.gitignore b/.gitignore index 1503014..81a1131 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ target/ Cargo.lock .idea/ + +imported_assets/ diff --git a/CHANGELOG.md b/CHANGELOG.md index cd80c18..283a19e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +- new example `asset_savers` + ## v0.12.0 - 29.11.2024 - Update to Bevy 0.15 diff --git a/Cargo.toml b/Cargo.toml index f21e7a8..1e09f9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,3 +88,8 @@ required-features = ["csv"] name = "multiple_formats" path = "examples/multiple_formats.rs" required-features = ["ron", "json"] + +[[example]] +name = "asset_savers" +path = "examples/asset_savers/asset_savers.rs" +required-features = ["ron", "json", "postcard", "bevy/file_watcher", "bevy/asset_processor"] diff --git a/README.md b/README.md index 256dfa2..4e6eb09 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,11 @@ ron files ending on `.level.ron` and so on... See the [examples](./examples) for working Bevy apps using the different formats. +## Asset savers / using the loaders in .meta files + +The more involved [example `asset_savers`](./examples/asset_savers) demonstrates how you can convert a json +asset into a processed postcard asset using the `JsonAssetLoader` and `PostcardAssetSaver`. + ## Compatible Bevy versions The main branch is compatible with the latest Bevy release. diff --git a/examples/asset_savers/asset_savers.rs b/examples/asset_savers/asset_savers.rs new file mode 100644 index 0000000..860dd33 --- /dev/null +++ b/examples/asset_savers/asset_savers.rs @@ -0,0 +1,83 @@ +use bevy::asset::processor::LoadTransformAndSave; +use bevy::asset::transformer::IdentityAssetTransformer; +use bevy::prelude::*; +use bevy_common_assets::json::{JsonAssetLoader, JsonAssetPlugin}; +use bevy_common_assets::postcard::{PostcardAssetPlugin, PostcardAssetSaver}; +use serde::{Deserialize, Serialize}; + +/// This example processes a json level asset into a postcard asset (binary format) +/// which is then loaded and rendered. If you run the example, the directory +/// `examples/asset_savers/imported_assets` is created and populated. +/// +/// Take a look at `examples/asset_savers/assets/trees.level.meta` to see the configuration +/// that tells Bevy which processor to use to convert the json asset into the postcard format. + +fn main() { + App::new() + .add_plugins(( + DefaultPlugins.set(AssetPlugin { + mode: AssetMode::Processed, + file_path: "examples/asset_savers/assets".to_string(), + processed_file_path: "examples/asset_savers/imported_assets/Default".to_string(), + ..default() + }), + PostcardAssetPlugin::::new(&["level"]), + JsonAssetPlugin::::new(&[]), + )) + .register_asset_processor::, + IdentityAssetTransformer, + PostcardAssetSaver, + >>(LoadTransformAndSave::new( + IdentityAssetTransformer::::default(), + PostcardAssetSaver::::default(), + )) + .init_state::() + .add_systems(Startup, setup) + .add_systems(Update, spawn_level.run_if(in_state(AppState::Loading))) + .run(); +} + +fn setup(mut commands: Commands, asset_server: Res) { + let level = LevelHandle(asset_server.load("trees.level")); + commands.insert_resource(level); + let tree = ImageHandle(asset_server.load("tree.png")); + commands.insert_resource(tree); + commands.spawn((Camera2d, Msaa::Off)); +} + +fn spawn_level( + mut commands: Commands, + level: Res, + tree: Res, + mut levels: ResMut>, + mut state: ResMut>, +) { + if let Some(level) = levels.remove(level.0.id()) { + for position in level.positions { + commands.spawn(( + Sprite::from_image(tree.0.clone()), + Transform::from_translation(position.into()), + )); + } + state.set(AppState::Level); + } +} + +#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] +enum AppState { + #[default] + Loading, + Level, +} + +#[derive(Resource)] +struct ImageHandle(Handle); + +#[derive(Resource)] +struct LevelHandle(Handle); + +#[derive(Deserialize, Serialize, Asset, TypePath)] +struct Level { + positions: Vec<[f32; 3]>, +} diff --git a/examples/asset_savers/assets/tree.png b/examples/asset_savers/assets/tree.png new file mode 100644 index 0000000000000000000000000000000000000000..0277561c9d713877b3309fe8771a514e01725fa9 GIT binary patch literal 830 zcmV-E1Ht@>P)EX>4Tx04R}tkv&MmKpe$iTZ>XE4lO9+kfAzRkSgM+RVYG*P%E_RU~=gfG-*gu zTpR`0f`cE6RR{I(nfjb4rr|lh?&0I>U7TlmpZjz4D+QAQK7n|a>4rtTK|H-_ z>74h8qpU0`#OK8023?T&k?XR{Z=6dG`*~*6$Y$n=qr^g~i{&n6WkV&NB91AlM*04n z%L?Z$&T6&J+V|uy3>UPOWvZqU!3vpUCQcPrMKk4BgcKjl_WO7x& z$gzMLR7j2={11M2YZfOHZc;c21Yd0XV-)D!1zHW;{yw(t)(H@J2ClS@zt#k1K1pwM zwAc|aunk;XcQknqxZDATo^;8O94SE4Un~OeXY@^ZAaV)nY;g*u00006VoOIv0AK)M0AOVlW=a46010qNS#tmY zE+YT{E+YYWr9XB6000McNlirueSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{009!kcF6rg|Y)fxP=DF zFhK6G;~#8G?`wU@Sx=vBCDt?{gb+dq8I|-f3AecQ*SMd(3=bd_WJt9jNG}1lf*_*= zUki$i9DE57q9OPk2nS6^T1rAhOZHQppvnO$$x#Vl4+OOU%sU{~1?C+fHP_b&rviI` z_Uy9<0KhnaP+5!vr~?$&0Wn{NECH*V9}WNj0Q3Sd|4)!50D#JsV9(Xy-rFG@kn?a) zE=au`#R0i5=)na!Jp#i!pm~EtOBa-AnHj1_sAS;90mOjtvlq9x^?mzn#!mO+UjwfO zAV%lwWdrH;cs7}f^bmYY2z(3y000000000000000001zlFKW_VPxvZ}_y7O^07*qo IM6N<$f+WpR9smFU literal 0 HcmV?d00001 diff --git a/examples/asset_savers/assets/tree.png.meta b/examples/asset_savers/assets/tree.png.meta new file mode 100644 index 0000000..764e18a --- /dev/null +++ b/examples/asset_savers/assets/tree.png.meta @@ -0,0 +1,12 @@ +( + meta_format_version: "1.0", + asset: Load( + loader: "bevy_image::image_loader::ImageLoader", + settings: ( + format: FromExtension, + is_srgb: true, + sampler: Default, + asset_usage: ("MAIN_WORLD | RENDER_WORLD"), + ), + ), +) \ No newline at end of file diff --git a/examples/asset_savers/assets/trees.level b/examples/asset_savers/assets/trees.level new file mode 100644 index 0000000..50871e9 --- /dev/null +++ b/examples/asset_savers/assets/trees.level @@ -0,0 +1,34 @@ +{ + "positions": [ + [ + 42.0, + 42.0, + 0.0 + ], + [ + 4.0, + 32.0, + 0.0 + ], + [ + 54.0, + 7.0, + 0.0 + ], + [ + -61.0, + 4.0, + 0.0 + ], + [ + -6.0, + -72.0, + 0.0 + ], + [ + 6.0, + -89.0, + 0.0 + ] + ] +} diff --git a/examples/asset_savers/assets/trees.level.meta b/examples/asset_savers/assets/trees.level.meta new file mode 100644 index 0000000..e6cb5a4 --- /dev/null +++ b/examples/asset_savers/assets/trees.level.meta @@ -0,0 +1,11 @@ +( + meta_format_version: "1.0", + asset: Process( + processor: "bevy_asset::processor::process::LoadTransformAndSave, bevy_asset::transformer::IdentityAssetTransformer, bevy_common_assets::postcard::PostcardAssetSaver>", + settings: ( + loader_settings: (), + transformer_settings: (), + saver_settings: (), + ), + ), +)