Git Product home page Git Product logo

bevy_asset_loader's Introduction

Hi there ๐Ÿ‘‹

bevy_asset_loader's People

Contributors

andrewhickman avatar arewerage avatar boolpurist avatar dasetwas avatar eerii avatar fraserlee avatar freiksenet avatar geirsagberg avatar inodentry avatar johanhelsing avatar lgrossi avatar maccesch avatar niklasei avatar onbjerg avatar rparrett avatar st0rmbtw avatar striezel avatar tguichaoua avatar thrombe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

bevy_asset_loader's Issues

Render feature does not seem to be applied correctly

The render feature of bevy_asset_loader controls whether the TextureAtlas assets can be used in the derive macro. It should be on by default and thus allow deriving AssetCollection for TextureAtlas fields. This does not seem to work in the context of bevy_game_template. Original comment on a different issue:


I don't know you mean which default features.

I'm just using your template https://github.com/NiklasEi/bevy_game_template and change the TextureAssets to use TextureAtlas in loading.rs and it reports that error.

And there is bevy = { version = "0.5.0", default-features = false }, I tried enable default features it still has that error.

If you mean default features of bevy_asset_loader then I think it's enabled.

Originally posted by @LeonLiuY in #7 (comment)

Remove ambiguities warnings

Remove all execution order ambiguities by either labelling and explicitly ordering systems or adding them to ambiguity sets.

Pull assets in FromWorld?

Is it possible to pull the loaded assets/fonts when constructing FromWorld for structs?

struct MenuMaterials {
    background: Handle<ColorMaterial>,
    normal: Handle<ColorMaterial>,
    hovered: Handle<ColorMaterial>,
    pressed: Handle<ColorMaterial>,
    font: Handle<Font>,
    font_color: Color,
}

impl FromWorld for MenuMaterials {
    fn from_world(world: &mut World) -> Self {
        // access fonts here??
    }
}

Support loading lists of files

Support loading lists of assets as Vec<HandleUntyped> or Vec<Handle<T>>.
This should work with listing the files in an attribute and as a dynamic asset.

See #44 for motivation

Loading ColorMaterial

Hey there, I love this crate! I ran into an issue though, I want to load ColorMaterial assets to use with GUI components, but it seems like if I add them like I add Textures and Fonts and so on, they fail to load. I don't get any warning messages or anything, but they don't display, and inspecting them in bevy_egui_inspector yields an error handle. Is this not a feature in the crate?

Using a loaded folder

Hello,

I see that you are currently implementing a feature to load a folder into a Vec<Handle<..>>.
I'm farily new to Bevy and Rust, so maybe I'm missing something here, but how do you plan this to be usable ?
Since Handles are just u64 identifiers, how do I know which handle I want to use/retreive ?

Here is an example:

#[derive(AssetCollection)]
struct IconCollection {
    #[asset(path = "icons", folder(typed))]
    all: Vec<Handle<Image>>,
}

fn show_actionbar_ui(
	ui: ResMut<..>,
	icon_collection: Res<IconCollection>,
	selected_actionbar_slot: Res<SelectedActionbarSlot>,
	selected_warrior: Res<SelectedWarrior>,
	wariors: Query<&Skills, With<Warrior>>
) {
	if let Some(skills) = warriors.get(selected_warrior.0) {
		for skill in skills.iter() {
			let icon_handle = icon_collection.all. // ???? = skill.icon_label;
			ui.show_icon(icon_handle);
		}
	}
}

Could it be more practical to load folders into a HashMap<String, Handle<..>>, using the filename as a key ?

Anyway, thanks for your work, this lib is great.

Need to use handles from collection during loading state

I'd like to set up a loading screen with a progress indicator that shows the percentage ready.

However, to spawn the UI with the Text for the percentage indicator, I need a Handle to my Font.

bevy_asset_loader only inserts the AssetCollection when those assets have actually been loaded, meaning it is not available for me to access when entering the loading state, to set up my UI.

Is it possible to make an AssetCollection available from the start? The only way I see is from the example without using a loading state. However, I want to use a loading state. I just want to be able to use the handles when entering it.

It's okay if the handles point to assets that aren't loaded yet. I just need to setup my loading/splash screen. The UI will just "pop in" when those specific assets become available.

Version 0.11.0 on Crates.io provides a lib.rs without a prelude section.

I would expect crates.io to link to a version of bevy_asset_loader which includes the prelude. such as https://github.com/NiklasEi/bevy_asset_loader/blob/main/bevy_asset_loader/src/lib.rs

It is currently pointing to a version which looks like https://github.com/NiklasEi/bevy_asset_loader/blob/bevy_main/bevy_asset_loader/src/lib.rs

This breaks the examples when Cargo.toml includes bevy_asset_loader = "0.11.0" instead of pointing to the github repo.

Rethink naming and rules for attributes

A few issues with the current naming and attribute rules:

  1. "Collection" is used for structs implementing AssetCollection and for folders and files as attributes
  2. It's not clear when attributes like collection or standard_material need to be set for dynamic asset fields (first yes, second no)
  3. Need to clarify "dynamic" more
    • What's a dynamic asset collection? The struct or the ron file?
    • What to call the ron files? Currently, "dynamic asset collection" or "dynamic asset collection file" to distinguish from the first.

For assets known at compile-time, attributes need to distinguish between:

  1. Handle
  2. Texture atlas
  3. Standard material
  4. folder
  5. typed folder
  6. collection
  7. typed collection

For assets resolved at run-time (dynamic assets), attributes need to distinguish the following cases at compile-time:

  1. Handle (including texture atlas and standard material)
  2. Option<Handle> (only supported for dynamic assets)
  3. folder/collection
  4. typed folder/collection

See the full_collection and full_dynamic_collection examples for current code.

AssetCollection derive broken?

Using bevy_asset_loader v0.8 with bevy v0.6, I've gotten an error with the following code which used to work and looks identical to the examples:

use bevy_asset_loader::AssetCollection;

#[derive(AssetCollection)]
pub struct TileAssets {
   /// Our tile collection
   #[asset(texture_atlas(tile_size_x = 32., tile_size_y = 32., columns = 1, rows = 1))]
   #[asset(path = "tiles/atlas.png")]
   pub atlas: Handle<TextureAtlas>
}

with compile error

error[E0425]: cannot find value `atlases` in this scope
 --> examples/tile_replace_stress.rs:4:10
  |
4 | #[derive(AssetCollection)]
  |          ^^^^^^^^^^^^^^^ not found in this scope
  |
  = note: this error originates in the derive macro `AssetCollection` (in Nightly builds, run with -Z macro-backtrace for more info)

With RUSTFLAGS="-Z macro-backtrace" it just unhelpfully points at asset_collection_derive().

Was there a name change recently?

Add a failure state alongside the success state?

It seems this crate only keeps track of Loaded assets, and waits indefinitely if some of the assets actually Failed loading. (I drew this conclusion based on the following code. Please correct me if I am wrong.) I don't believe the loading logic could recover after get_load_state returns Failed, so it seems that there is no point waiting any longer.

let done = loading_asset_handles
.handles
.iter()
.map(|handle| handle.id)
.map(|handle_id| asset_server.get_load_state(handle_id))
.filter(|state| state == &LoadState::Loaded)
.count();

Rather than waiting for the impossible, it would be great if this crate could also collect all the failures (ideally as asset paths) and transition to a "load failure" state, so the game could do graceful error reporting in this case. I believe there is already enough information for this kind of error reporting via the current AssetCollection interface.

I imagine in the new approach, Loaded and Failed both count as done in terms of progress tracking (perhaps also assert against NotLoaded and Unloaded, because it should be impossible to have such values returned from get_load_state in the loading stage), collect all the asset paths for Failed assets, and after done >= total, transition to either the "success" or the "failure" state according to the number of Failed assets. IMO tracking the Failed assets should not introduce too much overhead, so it could be the default behaviour (or of course, it could also be behind a feature gate). An alternative approach would be to unconditionally transition to the only "next" state, and let the systems there check the loading status manually by e.g. querying the existence of the AssetLoadingFailure resource.

Custom dynamic assets

Support loading and using custom types as dynamic assets.

E.g. it should be possible (with minimal setup), to automatically load files like this:

({
    "bakery": Building (
        position: [100., 0., 10.],
        image: "images/bakery.png"
    ),
    "baker": Npc (
        spawn: [100., 0., 10.],
        image: "images/baker.png",
    ),
})

This should not be bound to a certain file format.

Dynamic asset paths?

I want to use bevy_asset_loader, but I have a few assets paths that are not known at compile time. (they're currently passed as command line arguments, but could be from config file etc.)

Maybe there could be some way of setting the asset paths dynamically?

I tried implementing the AssetCollection trait manually, but the method that starts loading is:

fn load(asset_server: &Res<AssetServer>) -> Vec<HandleUntyped>

So there is no reference to either world or self, which means I don't think it's possible to get the kind of state I want (which is in a bevy resource)?

Loading TextureAtlas as a dynamic asset

I would like to configure which texture atlas to use at runtime. Each is currently defined in their own .assets resource like:

TextureAtlas (
    path: "textures/tilesets/standard_128.png",
    tile_size_x: 96.0,
    tile_size_y: 128,
    columns: 10,
    rows: 4
)

However I cannot seem to load these as a normal dynamic asset. I'm attempting to do the following:

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

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

    app.add_state(MyStates::Setup)
        .insert_resource(Msaa { samples: 1 })
        .add_plugins(DefaultPlugins)
        .add_system_set(
            SystemSet::on_enter(MyStates::Setup)
                .with_system(setup)
        )
        .add_system_set(
            SystemSet::on_enter(MyStates::Next)
                .with_system(spawn)
        )
    ;

    AssetLoader::new(MyStates::AssetLoading)
        .continue_to_state(MyStates::Next)
        .with_collection::<MyAssets>()
        .build(&mut app);

    app.run();
}

#[derive(Clone, Eq, PartialEq, Debug, Hash)]
enum MyStates {
    Setup,
    AssetLoading,
    Next,
}

#[derive(AssetCollection)]
struct MyAssets {
    #[asset(key = "tileset")]
    tileset: Handle<TextureAtlas>,
}

#[derive(Component, Deref, DerefMut)]
struct AnimationTimer(Timer);

fn setup(
    mut state: ResMut<State<MyStates>>,
    mut asset_keys: ResMut<DynamicAssets>,
) {
    asset_keys.register_asset(
        "tileset",
        DynamicAsset::File {
            path: "textures/tilesets/standard_128.assets".to_owned(),
        },
    );
    state
        .set(MyStates::AssetLoading)
        .expect("Failed to change state");
}

fn spawn(mut commands: Commands, assets: Res<MyAssets>) {
    commands.spawn_bundle(OrthographicCameraBundle::new_2d());

    commands
        .spawn_bundle(SpriteSheetBundle {
            texture_atlas: assets.tileset.clone(),
            ..default()
        })
        .insert(AnimationTimer(Timer::from_seconds(1., true)));
}
WARN bevy_asset::asset_server: encountered an error while loading an asset: 1:1: Expected struct

However it works fine when I define it as part of a dynamic collection:

.with_asset_collection_file("textures/tilesets/tileset.assets")
({
    "tileset": TextureAtlas (
        path: "textures/tilesets/standard_128.png",
        tile_size_x: 96.0,
        tile_size_y: 128,
        columns: 10,
        rows: 4
    )
})

The dynamic loading stops throwing a warning when I use the same format as a collection file, but fails to properly load the TextureAtlas.

Array syntax in RON dynamic collections?

Would it be possible to do something like this?

#[derive(AssetCollection)]
struct SpriteAnimationSequences {
    // maybe this needs a new attribute?
    // `collection(array)` or something,
    // to distinguish from `Files`
    #[asset(key = "anim.jumps", collection(typed)]
    jumps: Vec<Handle<TextureAtlas>>,
}
({
    // just use RON "array syntax"
    // to list as many items as we need
    "anim.jumps": [
        TextureAtlas (
            path: "jump_long.png",
            tile_size_x: 24.,
            tile_size_y: 32.,
            columns: 16,
            rows: 1,
        ),
        TextureAtlas (
            path: "jump_med.png",
            tile_size_x: 24.,
            tile_size_y: 32.,
            columns: 12,
            rows: 1,
        ),
        TextureAtlas (
            path: "jump_short.png",
            tile_size_x: 24.,
            tile_size_y: 32.,
            columns: 8,
            rows: 1,
        ),
    ],
})

Add dependencies of assets to the list of watched assets for transition out of loading state

Here's an example:
I use a custom loader for ldtk map files which loads and parses the ldtk file, and provides it as an asset to Bevy. I also load all of the images used for sprites/backgrounds/tiles/etc when I do this, and use the LoadedAsset::with_dependencies(...) member to add them as dependencies to my ldtk asset.

When I register this asset using an AssetCollection, as described in your readme, it seems to be correctly waiting on the ldtk file itself to load. However, it does not wait on all of the referenced images.

I will look at creating a dynamic asset description when constructing the asset, or simply adding the images separately. It would be a nice feature if your crate could detect this, however, due to the fact that the ldtk user could change what images they utilize at any time.

I don't know of other examples of assets with dependencies, but I imagine they could take advantage of this feature as well.

Support for nested folders

I would love to see some support for nested folder structures, for example:

- assets
    - scripts 
         - init.lua
         - hello.lua
         - more_scripts
             - script.lua

perhaps in the form of an argument to the asset attribute, maybe recursive ?

struct LuaAssets {
    #[asset(path = "scripts", folder(typed), recursive(true))]
    folder: Vec<Handle<LuaFile>>
}

alternatively the folder could be modelled as a dictionary, with keys representing the relative/absolute paths, in case these have some meaning to the developer.

In the case that the folder contains mixed assets, these could simply be ignored to accommodate use-cases where different asset types must be stored alongside each other.

Happy to help if necessary!

bevy_asset_loader doesn't wait for asset dependencies

In this minimal example the app will crash, since neither bevy's AssetServer or bevy_asset_loader wait for asset dependencies. So AssetA gets loaded successfully, but its slow dependency may not be loaded when you enter InGame state.

use bevy::prelude::*;
use bevy_asset_loader::*;
use iyes_loopless::prelude::*;

use anyhow::Error;
use bevy::reflect::TypeUuid;
use bevy::asset::{ 
    AssetLoader as AssetLoaderTrait, LoadContext, BoxedFuture, 
    LoadedAsset, Assets, AssetPath
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum GameState {
    Boot,
    InGame,
}

// Imagine Asset A is some lightweight fast-to-load asset (like a config)
#[derive(TypeUuid)]
#[uuid="cc570c16-ffd0-11ec-b939-0242ac120003"]
struct AssetA;

// And Asset B is some heavy slow-to-load asset (a quite big texture) 
#[derive(TypeUuid)]
#[uuid="cc570c16-ffd0-11ec-b939-0242ac120002"]
struct AssetB;

#[derive(Clone, Copy, Default)]
struct AssetALoader;
        
impl AssetLoaderTrait for AssetALoader {
    fn load<'a>(
        &'a self, _bytes: &'a [u8], load_context: &'a mut LoadContext
    ) -> BoxedFuture<Result<(), Error>> { 
        Box::pin(async move {
            let mut asset = LoadedAsset::new(AssetA);
            asset.add_dependency("B.b".into());
            load_context.set_default_asset(asset);
            Ok(())
        })
    }

    fn extensions(&self) -> &[&str] { &["a"] }
}

#[derive(Clone, Copy, Default)]
struct AssetBLoader;

impl AssetLoaderTrait for AssetBLoader {
    fn load<'a>(
        &'a self, _bytes: &'a [u8], load_context: &'a mut LoadContext
    ) -> BoxedFuture<Result<(), Error>> { 
        Box::pin(async move {
            use std::time::Duration;

            let asset = LoadedAsset::new(AssetB);
            // Pretend that we are parsing a large file (a .png)
            std::thread::sleep(Duration::from_secs(10));
            load_context.set_default_asset(asset);
            Ok(())
        })
    }

    fn extensions(&self) -> &[&str] { &["b"] }
}

#[derive(AssetCollection)]
struct ACol {
    #[asset(path = "A.a")]
    _asset: Handle<AssetA>,
}

fn test_enter(assets_a: Res<Assets<AssetA>>, assets_b: Res<Assets<AssetB>>) {
    assert!(assets_a.get::<AssetPath>("A.a".into()).is_some());
    println!("asset A loaded");
    assert!(assets_b.get::<AssetPath>("B.b".into()).is_some());
    println!("asset B loaded");
}

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

    app
        .add_plugins(DefaultPlugins)
        .add_asset::<AssetA>()
        .add_asset::<AssetB>()
        .init_asset_loader::<AssetALoader>()
        .init_asset_loader::<AssetBLoader>()
        .add_loopless_state(GameState::Boot)
        .add_enter_system(GameState::InGame, test_enter);
    
    AssetLoader::new(GameState::Boot)
        .continue_to_state(GameState::InGame)
        .with_collection::<ACol>()
        .build(&mut app);

    app.run();
}

Load folder?

Is it possible to load a whole folder into Vec<Handle<MyType>>?

Error when using `progress_tracking` and `progress_tracking_stageless` features

When trying to delay the end of loading assets using iyes_progress, an error occurs:

thread 'main' panicked at 'State Transiton Stage not found (assuming auto-added label)', C:\Users\Anton\.cargo\registry\src\github.com-1ecc6299db9ec823\iyes_loopless-0.5.1\src\state.rs:239:25
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\bevy_template.exe` (exit code: 101)

bevy: 0.7
bevy_asset_loader: branch main

Cargo.toml:

[features]
default = [
    # https://github.com/bevyengine/bevy/blob/main/docs/cargo_features.md
    "bevy/bevy_winit",
    "bevy/render",
    "bevy/png",

    "bevy_asset_loader/2d",
    "bevy_asset_loader/dynamic_assets",
    "bevy_asset_loader/stageless",
    "bevy_asset_loader/progress_tracking",
    "bevy_asset_loader/progress_tracking_stageless",
]

dev = [
    "bevy/dynamic",
]

[dependencies]
bevy = { version = "0.7", default-features = false }
iyes_loopless = { git = "https://github.com/NiklasEi/iyes_loopless", branch = "loopless-schedule-ext-trait" }
bevy-inspector-egui = "0.11.0"
bevy_asset_loader = { git = "https://github.com/NiklasEi/bevy_asset_loader", branch = "main" }
iyes_progress = "0.3.0"

lib.rs:

mod loading;

use bevy::prelude::*;
use iyes_loopless::prelude::*;

pub struct GamePlugin;

impl Plugin for GamePlugin {
    fn build(&self, app: &mut App) {
        app.add_loopless_state(GameState::Loading)
            .add_plugin(loading::LoadingPlugin);
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GameState {
    Loading,
    MainMenu,
    Gameplay,
}

loading.rs:

use bevy::prelude::*;
use bevy_asset_loader::prelude::*;
use iyes_loopless::prelude::*;
use iyes_progress::{ProgressCounter, ProgressPlugin};

use crate::GameState;

const TIME_FOR_SPLASH_SCREEN: f64 = 5.0;

pub struct LoadingPlugin;

impl Plugin for LoadingPlugin {
    fn build(&self, app: &mut App) {
        app.add_loading_state(
            LoadingState::new(GameState::Loading)
                .continue_to_state(GameState::MainMenu)
                .with_dynamic_collections::<StandardDynamicAssetCollection>(vec!["dynamic.assets"])
                .with_collection::<ImageAssets>()
                .with_collection::<AudioAssets>()
                .with_collection::<FontAssets>(),
        )
        .add_plugin(ProgressPlugin::new(GameState::Loading))
        .add_system(make_loading_delay.run_in_state(GameState::Loading));
    }
}

#[derive(AssetCollection)]
struct ImageAssets {}

#[derive(AssetCollection)]
struct AudioAssets {}

#[derive(AssetCollection)]
struct FontAssets {}

fn make_loading_delay(time: Res<Time>, progress: Res<ProgressCounter>) {
    let condition = time.seconds_since_startup() > TIME_FOR_SPLASH_SCREEN;
    progress.manually_track(condition.into());
}

Track 0.7

With the release of Bevy 0.7, plugins will probably need to be reconfigured to track it.

load-bearing `track_fake_long_task` system in `stageless_progress` example

In the new iyes_loopless stageless_progress example, the track_fake_long_task system is load-bearing. If removed, the assets fail to be available.

If you remove the system in the current example, the current progress is logged out as done:0, total: 0.

2022-06-01T01:44:05.670996Z  INFO stageless_progress: Current progress: Progress { done: 0, total: 0 }

and if you add a requirement for the TextureAssets in quit, you get a crash because Res<TextureAssets> is not available.

fn quit(
    mut quit: EventWriter<AppExit>,
    // textures: Res<TextureAssets>,
) {
    info!("quitting");
    quit.send(AppExit);
}
2022-06-01T01:40:13.660762Z  WARN bevy_ecs::schedule::graph_utils: bevy_asset_loader::asset_loader::stageless::systems::run_loading_state<stageless_progress::MyStates> wants to be after unknown label: Preparation
2022-06-01T01:40:13.662065Z  INFO stageless_progress: Current progress: Progress { done: 0, total: 0 }
thread 'Compute Task Pool (3)' panicked at 'Resource requested by stageless_progress::quit does not exist: stageless_progress::TextureAssets', /Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.7.0/src/system/system_param.rs:319:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'task has failed', /Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.2.0/src/task.rs:425:45
thread 'main' panicked at 'Task thread panicked while executing.: Any { .. }', /Users/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.7.0/src/task_pool.rs:77:21

There's a possibly unrelated warning as well relating to the Preparation label.

2022-06-01T01:40:13.660762Z  WARN bevy_ecs::schedule::graph_utils: bevy_asset_loader::asset_loader::stageless::systems::run_loading_state<stageless_progress::MyStates> wants to be after unknown label: Preparation

I think this is because of a race condition relating to time.seconds_since_startup(). With the delay, it's fine, without the delay it fails.

Support for more than files in StandardMaterial

This plugin has been very helpful so far. However, I have a use case that is a little annoying to work around.

#[derive(AssetCollection)]
struct ImageAssets {
    #[asset(path = "attack_uv.png")]
    attack_uv: Handle<Image>,
}

#[derive(Default)]
struct MaterialAssets {
    attack: Handle<StandardMaterial>,
    blank: Handle<StandardMaterial>,
    empty: Handle<StandardMaterial>,
}

fn material_loader(
    mut materials: ResMut<Assets<StandardMaterial>>,
    mut material_assets: ResMut<MaterialAssets>,
    image_assets: Res<ImageAssets>,
) {
    material_assets.attack = materials.add(StandardMaterial {
        base_color_texture: Some(image_assets.attack_uv.clone()),
        ..default()
    });
    material_assets.blank = materials.add(StandardMaterial::default()); // use default
    material_assets.empty = materials.add(StandardMaterial {
        base_color: Color::rgba(1., 0., 0., 0.), // custom colour
        alpha_mode: AlphaMode::Blend, // Note: won't be necessary in 0.8
        ..default()
    });
}

From what I understand, currently with StandardMaterial it is possible to do

    #[asset(standard_material)]
    #[asset(path = "attack.png")]
    attack: Handle<StandardMaterial>,

However, I have a resource that has a combination of materials from an image, and some that are just a base colour, as well as with default. I know this plugin focuses mainly focuses on loading assets, but being able to manage assets like this without boilerplate would be immensely useful.

Race condition on multiple similar AssetLoaders

Hello,

I am currently trying to apply clean asset loading to two of my Plugin.

As per the guide, I am initializing a loopless_state with app.add_loopless_state(GameState::Loading) before using any of my plugins.

I am doing the following :

In MeteorPlugin :

AssetLoader::new(GameState::Loading)
            .continue_to_state(GameState::Level)
            .with_collection::<MeteorAssets>()
            .build(app);

app.add_enter_system(GameState::Level, spawn_asteroid_field);

In ShipPlugin :

 AssetLoader::new(GameState::Loading)
            .continue_to_state(GameState::Level)
            .with_collection::<LoadingShipAssets>()
            .build(app);

app.add_enter_system(GameState::Level, setup_spaceship_system)

When I was using the AssetLoader in only one Plugin everything went fine. But as soon as I added asset collection loading to the other, I believe the GameState::Level was entered too soon and made my code panic since all the assets were not loaded yet.

It kinda looks like a race condition between each AssetLoader.

I thought when declaring more than one AssetLoader on a given state, it would aggregate all the collections needed, wait for all of them to load, and then transition to the given state.

Thank you for your time!

Support Option<Handle> for dynamic asset collections

If I define a dynamic asset collection, but a certain key cannot be resolved at run time, the plugin currently panics.

Is it possible to not panic if the asset field is Option<Handle> and instead write None in these cases?

Support folders as dynamic assets

This will require the folder attribute on the collection field because we need to know the field type at compile time. Should be the same as the optional dynamic assets.

Split `render` cargo feature into 2d and 3d

I like to selectively depend on either bevy_sprite or bevy_pbr depending on whether the project in question is a 2d or 3d game, to not include unnecessary parts of Bevy into my projects. Currently, bevy_asset_loader requires pulling in both. Would be nice if the two were separate.

Configure dynamic assets file ending

The readme states

should be part of a .assets file in ron format (the file ending can be configured)

However the asset_collection_file_ending member is private and I don't see a method to set it.

Folder as asset in web deployment

I am having trouble getting a folder loaded when running on the web.
I am using your template for building and deploying my stuff to github pages, but a folder that is loading fine on windows is panicking on the web.

You should see the problem on this deployment: (https://troels51.github.io/hex_map_bevy/)
And it is panicking like this in the log
panicked at 'called `Result::unwrap()` on an `Err` value: AssetFolderNotADirectory("hexes")', src\loading\hex.rs:20:10

Support more than one Plugin instance in the same State

Currently, two plugin instances with the same "loading State" will enter a race for how can change the state first. The slower plugin will not finish loading the collection. Maybe multiple instances of the plugin could communicate via a resource to coordinate that only the slowest one changes the state.

Add Loading statistics

It would be handy to get some statistics from AssetLoader so while it's loading we can display some progress UI. It'd be on the programmer to put their systems in the right State and poll AssetLoader appropriately.

Assets Handles

I am new to bevy and ran into a few issues today and both came back to be something with bevy_asset_loader, though maybe I am missing something. Note that I am forked and using bevy_main, (no rev)

  1. Assets Unloaded

So after adding a few *.wav files to an AssetCollection, I would have an issue where the state change state on load never happening, and the asset collections never got added as resources so panic. Funny enough though if I ran in --release they would. After some poking around got some info from Res<LoadingAssetHandles>

AudioSource Collection - Not release

"bevy_asset::handle::Handle<bevy_kira_audio::source::AudioSource>" - NotLoaded
"bevy_asset::handle::Handle<bevy_kira_audio::source::AudioSource>" - Loading
"bevy_asset::handle::Handle<bevy_kira_audio::source::AudioSource>" - Loading
"bevy_asset::handle::Handle<bevy_kira_audio::source::AudioSource>" - Unloaded
"bevy_asset::handle::Handle<bevy_kira_audio::source::AudioSource>" - Unloaded
...

Texture Collection- Not release

"bevy_asset::handle::Handle<bevy_render::texture::texture::Texture>" - NotLoaded
"bevy_asset::handle::Handle<bevy_render::texture::texture::Texture>" - Loading
"bevy_asset::handle::Handle<bevy_render::texture::texture::Texture>" - Loading
"bevy_asset::handle::Handle<bevy_render::texture::texture::Texture>" - Unloaded
"bevy_asset::handle::Handle<bevy_render::texture::texture::Texture>" - Unloaded
...

Font Collection - Not release - Works

"bevy_asset::handle::Handle<bevy_text::font::Font>" - Loading
"bevy_asset::handle::Handle<bevy_text::font::Font>" - Loaded

With Release - All 3 works

"bevy_asset::handle::Handle<bevy_render::texture::texture::Texture>" - NotLoaded
"bevy_asset::handle::Handle<bevy_kira_audio::source::AudioSource>" - NotLoaded
"bevy_asset::handle::Handle<bevy_text::font::Font>" - Loading
"bevy_asset::handle::Handle<bevy_text::font::Font>" - Loaded
"bevy_asset::handle::Handle<bevy_kira_audio::source::AudioSource>" - Loaded
"bevy_asset::handle::Handle<bevy_render::texture::texture::Texture>" - Loaded

Wtf was going on with Asset LoadState. It was at this point I ran across [bevy 2347]bevyengine/bevy#2347)

Related?

  1. Audio Handle Issue

I was working on adding auto with your bevy_kira_audio, (thanks for all you contribute btw) while I couldn't get the sounds after the first few frames. I keep thinking I was using bevy_kira_audio wrong, and after refactored my code like 3 times, I finally tried removing bevy_asset_loader from the picture, and boom it works.

I set up a toy example to show the problem, am I missing something?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.