How to Use Assets
This guide covers the basic usage of assets into Amethyst for existing supported formats. For a list of supported formats, please use this search for "Format" in the API documentation, and filter by the following crates:
- amethyst_assets
- amethyst_audio
- amethyst_gltf
- amethyst_locale
- amethyst_ui
Steps
-
Instantiate the Amethyst application with the assets directory.
extern crate amethyst; use amethyst::{ prelude::*, ecs::{World, WorldExt}, utils::application_root_dir, }; pub struct LoadingState; impl SimpleState for LoadingState {} fn main() -> amethyst::Result<()> { // Sets up the application to read assets in // `<app_dir>/assets` let app_root = application_root_dir()?; let assets_dir = app_root.join("assets"); //.. let world = World::new(); let game_data = GameDataBuilder::default(); let mut game = Application::new(assets_dir, LoadingState, game_data)?; game.run(); Ok(()) }
-
Ensure that the
Processor<A>
system for asset typeA
is registered in the dispatcher.For asset type
A
,Processor<A>
is aSystem
that will asynchronously loadA
assets. Usually the crate that providesA
will also registerProcessor<A>
through aSystemBundle
. Examples:FontAsset
is provided byamethyst_ui
,UiBundle
registersProcessor<FontAsset>
.Source
is provided byamethyst_audio
,AudioBundle
registersProcessor<Source>
.SpriteSheet
is not added by a bundle, soProcessor<SpriteSheet>
needs to be added to the builder.
-
Use the
Loader
resource to load the asset.extern crate amethyst; use amethyst::{ assets::{AssetStorage, Handle, Loader, ProgressCounter}, ecs::{World, WorldExt}, prelude::*, renderer::{formats::texture::ImageFormat, Texture}, utils::application_root_dir, }; pub struct LoadingState { /// Tracks loaded assets. progress_counter: ProgressCounter, /// Handle to the player texture. texture_handle: Option<Handle<Texture>>, } impl SimpleState for LoadingState { fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { let loader = &data.world.read_resource::<Loader>(); let texture_handle = loader.load( "player.png", ImageFormat::default(), &mut self.progress_counter, &data.world.read_resource::<AssetStorage<Texture>>(), ); self.texture_handle = Some(texture_handle); } } fn main() -> amethyst::Result<()> { let app_root = application_root_dir()?; let assets_dir = app_root.join("assets"); let game_data = GameDataBuilder::default(); let mut game = Application::new( assets_dir, LoadingState { progress_counter: ProgressCounter::new(), texture_handle: None, }, game_data, )?; game.run(); Ok(()) }
-
Wait for the asset to be loaded.
When
loader.load(..)
is used to load anAsset
, the method returns immediately with a handle for the asset. The asset loading is handled asynchronously in the background, so if the handle is used to retrieve the asset, such as withworld.read_resource::<AssetStorage<Texture>>()
.get(texture_handle)
, it will returnNone
until theTexture
has finished loading.extern crate amethyst; use amethyst::{ assets::{Handle, ProgressCounter}, prelude::*, renderer::Texture, }; pub struct GameState { /// Handle to the player texture. texture_handle: Handle<Texture>, } impl SimpleState for GameState {} pub struct LoadingState { /// Tracks loaded assets. progress_counter: ProgressCounter, /// Handle to the player texture. texture_handle: Option<Handle<Texture>>, } impl SimpleState for LoadingState { fn update( &mut self, _data: &mut StateData<'_, GameData<'_, '_>>, ) -> SimpleTrans { if self.progress_counter.is_complete() { Trans::Switch(Box::new(GameState { texture_handle: self.texture_handle .take() .expect( "Expected `texture_handle` to exist when \ `progress_counter` is complete." ), })) } else { Trans::None } } }
The asset handle can now be used:
extern crate amethyst; use amethyst::{ assets::Handle, prelude::*, renderer::Texture, }; pub struct GameState { /// Handle to the player texture. texture_handle: Handle<Texture>, } impl SimpleState for GameState { fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { // Create the player entity. data.world .create_entity() // Use the texture handle as a component .with(self.texture_handle.clone()) .build(); } }