NiklasEi / bevy_asset_loader

Bevy plugin helping with asset loading and organization
Apache License 2.0
481 stars 53 forks source link

Crash when loading multiple collections #123

Closed chungwong closed 1 year ago

chungwong commented 1 year ago

Full code to reproduce the problem

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

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

#[derive(AssetCollection, Resource)]
struct MainMenuAssets {
    #[asset(key = "single_file")]
    single_file: Handle<AudioSource>,
}

#[derive(Clone, Eq, PartialEq, Debug, Hash, Default, States)]
enum MyStates {
    #[default]
    SplashAssetLoading,
    Splash,
    MainMenuAssetLoading,
    MainMenu,
}

fn main() {
    App::new()
        .add_state::<MyStates>()
        .add_plugins(DefaultPlugins)
        .add_plugin(SplashPlugin)
        .add_plugin(MainMenuPlugin)
        .run();
}

struct SplashPlugin;
impl Plugin for SplashPlugin {
    fn build(&self, app: &mut App) {
        app.insert_resource(SplashTimer(Timer::from_seconds(1.0, TimerMode::Once)))
            .add_loading_state(
                LoadingState::new(MyStates::SplashAssetLoading).continue_to_state(MyStates::Splash),
            )
            .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>(
                MyStates::SplashAssetLoading,
                "splash.assets.ron",
            )
            .add_system(splash_countdown);
    }
}

#[derive(Resource, Deref, DerefMut)]
struct SplashTimer(Timer);

fn splash_countdown(
    mut game_state: ResMut<NextState<MyStates>>,
    time: Res<Time>,
    mut timer: ResMut<SplashTimer>,
) {
    if timer.tick(time.delta()).finished() {
        game_state.set(MyStates::MainMenuAssetLoading);
    }
}

struct MainMenuPlugin;

impl Plugin for MainMenuPlugin {
    fn build(&self, app: &mut App) {
        app
            .add_loading_state(
            LoadingState::new(MyStates::MainMenuAssetLoading).continue_to_state(MyStates::MainMenu),
        )
        .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>(
            MyStates::MainMenuAssetLoading,
            "main_menu.assets.ron",
        )
        .add_collection_to_loading_state::<_, MainMenuAssets>(MyStates::MainMenuAssetLoading);
    }
}

The app state flow as SplashAssetLoading > Splash(with splash_countdown fn) > MainMenuAssetLoading > MainMenu. When it the countdown is done and appstate changes to MainMenuAssetLoading, it crashes with this error

thread 'main' panicked at 'Resource requested by (bevy_ecs::change_detection::ResMut<bevy_asset_loader::dynamic_asset::DynamicAssetCollections<mytest::MyStates>>, bevy_ecs::change_detection::ResMut<bevy_asset_loader::loading_state::LoadingAssetHandles<bevy_asset_loader::standard_dynamic_asset::StandardDynamicAssetCollection>>, bevy_ecs::change_detection::Res<bevy_asset::asset_server::AssetServer>, bevy_ecs::change_detection::Res<bevy_ecs::schedule::state::State<mytest::MyStates>>, bevy_ecs::change_detection::ResMut<bevy_asset_loader::loading_state::AssetLoaderConfiguration<mytest::MyStates>>) does not exist: bevy_asset_loader::loading_state::LoadingAssetHandles<bevy_asset_loader::standard_dynamic_asset::StandardDynamicAssetCollection>', /home/chung/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.10.1/src/system/system_param.rs:555:17
NiklasEi commented 1 year ago

I think this comes from the same underlying issue as #126