bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.68k stars 3.53k forks source link

Allow loading TextureAtlas with the asset server, configuring its layout using a .meta file #10679

Open idanarye opened 10 months ago

idanarye commented 10 months ago

What problem does this solve or what need does it fill?

To create a TextureAtlas, one must currently load the Image first and then create the texture atlas object and manually add it to the Assets<TextureAtlas> resource.

This is less convenient than other asset loading, which you just need to load with the asset server. This also mean that you can't just let the asset server handle the unloading of the spritesheet - because the texture atlas which depends on it and holds a reference to it is not retrieved by the asset server, which means you have to either store an handle to it in a resource or risk creating it multiple times.

What solution would you like?

Assets V2 introduced .meta files adjacent to the assets. These files can override the asset loader used to load the asset (which would otherwise depend on the file extension), and provide settings for it. We could use these settings to specify the rows and columns of the texture atlas.

Additionally, a (Bevy based) tool could be made to edit these meta files graphically.

What alternative(s) have you considered?

I've found some projects that use an .atlas extension for a similar purpose:

I could not, however, find actual examples or specification of that extension, and I suspect the syntax is different between them. Had there been a standard format for an adjacent file that defines a sprite sheet, with ecosystem support (e.g. - sprite editors able to write these files when exporting to PNG), it may have been preferable to use that format.

Of course, Bevy could also start it's own such extension.

idanarye commented 10 months ago

One drawback of the .meta file approach is that we won't have a path for the Image asset. This means that if, for whatever reason, the TextureAtlas asset gets unloaded while the Image itself remains, loading the TextureAtlas again would also load the Image again (even though it is still loaded).

Unless, maybe, the Image can be stored as a labeled asset of the TextureAtlas? So sprite.png will be a texture atlas, and sprint.png#data will be the actual Image? Can this be done, in a way that prevent duplication of sprite.png#data?