Closed mpowell90 closed 11 months ago
It is possible, but requires a bit more code. The enum needs to be manually mapped, but I am sure there is a lot of potential for improvement using macros to auto generate the conversion from enum variant to file name and creating a list of all enum variants (fyi the States
derive macro from Bevy also does that).
Please ignore that I used images instead of scenes. I just wanted to test this and have no scene files lying around.
use bevy::prelude::*;
use bevy::utils::HashMap;
use bevy_asset_loader::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_state::<MyStates>()
.add_loading_state(
LoadingState::new(MyStates::AssetLoading).continue_to_state(MyStates::Next),
)
.add_collection_to_loading_state::<_, UnitAssets>(MyStates::AssetLoading)
.init_resource_after_loading_state::<_, MilitaryUnitAssets>(MyStates::AssetLoading)
.insert_resource(Msaa::Off)
.add_system(draw.in_schedule(OnEnter(MyStates::Next)))
.run();
}
#[derive(AssetCollection, Resource)]
struct UnitAssets {
#[asset(path = "images", collection(typed, mapped))]
unit_folder: HashMap<String, Handle<Image>>,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum MilitaryUnitType {
Basic,
Defensive,
Offensive,
Elite,
}
impl MilitaryUnitType {
fn file_path(&self) -> &'static str{
match self {
MilitaryUnitType::Basic => "background.png",
MilitaryUnitType::Defensive => "tree.png",
MilitaryUnitType::Offensive => "zombie.png",
MilitaryUnitType::Elite => "player.png"
}
}
}
#[derive(Debug, Deref, DerefMut, Resource)]
pub struct MilitaryUnitAssets(pub HashMap<MilitaryUnitType, Handle<Image>>);
impl FromWorld for MilitaryUnitAssets {
fn from_world(world: &mut World) -> Self {
let units = world
.get_resource_mut::<UnitAssets>()
.expect("Failed to get UnitAssets");
let mut map: HashMap<MilitaryUnitType, Handle<Image>> = default();
for unit_type in [MilitaryUnitType::Basic, MilitaryUnitType::Elite, MilitaryUnitType::Defensive, MilitaryUnitType::Offensive] {
let path = format!("images/{}", unit_type.file_path());
let unit = units.unit_folder.get(&path).unwrap_or_else(|| panic!("Asset file for {:?} is missing at {}", unit_type, path));
map.insert(unit_type, unit.clone());
}
MilitaryUnitAssets(map)
}
}
fn draw(
combined_texture: Res<MilitaryUnitAssets>,
) {
println!("{:?}", combined_texture);
}
#[derive(Clone, Eq, PartialEq, Debug, Hash, Default, States)]
enum MyStates {
#[default]
AssetLoading,
Next,
}
@NiklasEi thanks for the code example, this has helped achieve what I needed!
Hi @NiklasEi, I'm interested in using your library as it seems to do exactly what I need.
My current asset resource implementation uses an enum as the key of a hashmap, which I would like to retain as the enum variants tie in with my system design. I'd like to achieve something like the following, is it possible?
Many thanks!