Closed lgrossi closed 7 months ago
This might have been fixed by the changes to texture atlases in Bevy 0.13. The layout and the sprites are now separated:
#[derive(AssetCollection, Resource)]
pub struct SpriteAssets {
#[asset(texture_atlas(tile_size_x = 96., tile_size_y = 96., columns = 8, rows = 1))]
pub atlas_layout_96_96: Handle<TextureAtlasLayout>,
#[asset(image(sampler = nearest))]
#[asset(path = "sprite-sheets-96", collection(typed, mapped))]
pub sprite_sheets_96_96: HashMap<String, Handle<Image>>,
#[asset(texture_atlas(tile_size_x = 32., tile_size_y = 32., columns = 12, rows = 12))]
pub atlas_layout_32_32: Handle<TextureAtlasLayout>,
#[asset(image(sampler = nearest))]
#[asset(path = "sprite-sheets-32", collection(typed, mapped))]
pub sprite_sheets_32_32: HashMap<String, Handle<Image>>,
}
The layout of an atlas is no longer connected to an asset file and can be reused for as many image files as you like. See the changed Bevy example on how to use the layout with the image handles.
Yes, the refactor that Bevy did on the way atlas are handled in 0.13 is great, it is now unified with the way single sprites are handled and it solves a lot of drawbacks of the previous design, super happy with it. I think we can close this one for now, I'll re-open it if I find any limitations in the new approach.
@NiklasEi One thing that showed up while taking this approach is that I now need a key for each layout. I wonder if it's possible to dynamically load all layouts in an array of layouts from ron instead.
Any thoughts on that?
E.g. having:
({
"layout.one_by_one": TextureAtlasLayout (
tile_size_x: 32.,
tile_size_y: 32.,
columns: 12,
rows: 12,
),
"layout.one_by_two": TextureAtlasLayout (
tile_size_x: 32.,
tile_size_y: 64.,
columns: 12,
rows: 6,
),
"layout.two_by_one": TextureAtlasLayout (
tile_size_x: 64.,
tile_size_y: 32.,
columns: 6,
rows: 12,
),
"layout.two_by_two": TextureAtlasLayout (
tile_size_x: 64.,
tile_size_y: 64.,
columns: 6,
rows: 6,
),
})
I need to individually declare each layout like:
#[asset(key = "layout.one_by_one")]
atlas_layout: Handle<TextureAtlasLayout>,
Is there a way to have it multiple, like we do with file paths and folders?
#[asset(key = "layouts", collection(typed, mapped))]
files_typed_mapped: HashMap<String, Handle<TextureAtlasLayout>>,
Personally, I would prefer to load them one by one, because it's nicer to use a struct field directly than having to index it. Unless you want to be able to iterate over them?
Well, the whole setup is kinda of dynamic, so needing to access them one by one is a bit convoluted also it aims to be extendable (aka you can define your own layouts) so having each of them as a different struct or a different field in the struct would not fly.
What I'm doing right now is just doing custom asset where my custom asset is just CustomAsset(Vec
({
"layout.main": MultiStandardDynamicAsset([
TextureAtlasLayout (
tile_size_x: 32.,
tile_size_y: 32.,
columns: 12,
rows: 12,
),
TextureAtlasLayout (
tile_size_x: 32.,
tile_size_y: 64.,
columns: 12,
rows: 6,
),
TextureAtlasLayout (
tile_size_x: 64.,
tile_size_y: 32.,
columns: 6,
rows: 12,
),
TextureAtlasLayout (
tile_size_x: 64.,
tile_size_y: 64.,
columns: 6,
rows: 6,
),
]),
})
Didn't stop to think about the mapping yet, tho.
Context
First of all, thanks a lot for this crate, it makes asset loading incredibly less convoluted. I'm using it in different situations for now and it works greatly. The only challenge I faced so far was the lack of possibility of loading a folder of atlases or multiple atlases files, when dealing with a large amount of sprite atlases that are always the same.
I'll give some examples to illustrate:
Basic case: a folder with many atlases that have the same grid
Multiple assets grids
Dynamic Load
Workarounds
Currently, what I do to achieve the same is basically to load the folder with all sheets and build the grids based on the configs I have for each grid group. It's already way nicer to do so than manually loading everything, but is still a bit convoluted.
The downside of this approach is higher memory usage than using just the atlases, when getting rid of the Image handles right after. Also, I still kept the old flow (lazy loaded file by file) since it gives an alternative for faster loading and reduced memory usage, but lazy loading is limited, not every scenario deals well with it.
Feature Request
Would be super nice if this crate in the future allowed more custom ways to deal with a big amount of atlases like the one mentioned above. I'm not sure if the suggestions above are the best way to go, but I would love to spark discussions around this subject and possibilities.