#bevy #gamedev #asset #assets

macro bevy_asset_loader_derive

Macro implementation for #[derive(AssetCollection)]

9 releases (breaking)

Uses new Rust 2021

0.8.0 Jan 8, 2022
0.6.0 Oct 1, 2021
0.4.0 Jun 26, 2021

#382 in Game dev

Download history 124/week @ 2021-10-04 68/week @ 2021-10-11 39/week @ 2021-10-18 45/week @ 2021-10-25 55/week @ 2021-11-01 28/week @ 2021-11-08 48/week @ 2021-11-15 62/week @ 2021-11-22 98/week @ 2021-11-29 86/week @ 2021-12-06 90/week @ 2021-12-13 29/week @ 2021-12-20 85/week @ 2021-12-27 132/week @ 2022-01-03 247/week @ 2022-01-10 281/week @ 2022-01-17

758 downloads per month
Used in 2 crates (via bevy_asset_loader)


506 lines

Bevy asset loader

crates.io docs license crates.io

This Bevy plugin reduces boilerplate when loading game assets. The crate offers the AssetCollection trait and can automatically load structs that implement it. The trait can be derived.

The main branch and all current releases support Bevy version 0.5. If you like living on the edge, take a look at the bevy_main branch, which tries to stay close to Bevy's development.

How to use

The AssetLoader is constructed with two states (see the cheatbook on states). During the first state it will load the assets and check up on the loading status in every frame. When the assets are done loading, the collections will be inserted as resources, and the plugin switches to the second state.

For structs with named fields that are either asset handles or implement default, AssetCollection can be derived. You can add as many AssetCollections to the loader as you want by chaining with_collection calls. To finish the setup, call the build function with your AppBuilder.

Now you can start your game logic from the second configured state and use the asset collections as resources in your systems.

use bevy::prelude::*;
use bevy_asset_loader::{AssetLoader, AssetCollection};

fn main() {
  let mut app = App::new();
          .build(&mut app);

struct AudioAssets {
  #[asset(path = "walking.ogg")]
  walking: Handle<AudioSource>

struct ImageAssets {
  #[asset(path = "images/player.png")]
  player: Handle<Image>,
  #[asset(path = "images/tree.png")]
  tree: Handle<Image>,

fn use_my_assets(_image_assets: Res<ImageAssets>, _audio_assets: Res<AudioAssets>) {
  // do something using the asset handles from the resources

#[derive(Clone, Eq, PartialEq, Debug, Hash)]
enum GameState {

See two_collections.rs for a complete example.

Dynamic assets

It is possible to decide an asset file path at run time. This is done via the resource AssetKeys which is basically a map of asset keys to their file paths. The AssetLoader initializes the resource and reads it during the loading state. You should define all asset keys and their paths in a previous state.

use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;

struct ImageAssets {
  #[asset(key = "player")]
  player: Handle<Image>,

Take a look at the dynamic_asset example to see how this can work in your code.

There will likely be additions to this feature in the future. The goal is to allow defining all the other asset attributes dynamically, too (e.g., texture atlas options).

Loading a folder as asset

You can load all assets in a folder and keep them in an AssetCollection as a vector of untyped handles.

use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;

struct MyAssets {
    #[asset(folder = "images")]
    folder: Vec<HandleUntyped>,

Loading standard materials

You can directly load standard materials if you enable the feature render. For a complete example please take a look at standard_material.rs.

use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;

struct MyAssets {
    #[asset(path = "images/player.png")]
    player: Handle<StandardMaterial>,

Loading texture atlases

You can directly load texture atlases from sprite sheets if you enable the feature render. For a complete example please take a look at atlas_from_grid.rs.

use bevy::prelude::*;
use bevy_asset_loader::AssetCollection;

struct MyAssets {
    #[asset(texture_atlas(tile_size_x = 100., tile_size_y = 96., columns = 8, rows = 1, padding_x = 12., padding_y = 12.))]
    #[asset(path = "images/sprite_sheet.png")]
    sprite: Handle<TextureAtlas>,

Initialize FromWorld resources

In situations where you would like to prepare other resources based on your loaded assets you can use AssetLoader::init_resource to initialize FromWorld resources. See init_resource.rs for an example that loads two images and then combines their pixel data into a third image.

AssetLoader::init_resource does the same as Bevy's App::init_resource, but at a different point in time. While Bevy inserts your resources at the very beginning, the AssetLoader will do so after having inserted your loaded asset collections. That means that you can use your asset collections in the FromWorld implementations.

Compatible Bevy versions

The main branch is compatible with the latest Bevy release, while the branch bevy_main tracks the main branch of Bevy.

Compatibility of bevy_asset_loader versions:

bevy_asset_loader bevy
0.8 0.6
0.1 - 0.7 0.5
main 0.6
bevy_main main


Licensed under either of

at your option.

Assets in the examples might be distributed under different terms. See the readme in the bevy_asset_loader/examples directory.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


~17K SLoC