Unify sprites and sprite sheets#5072
Conversation
| use bevy_reflect::Reflect; | ||
| use bevy_render::texture::{Image, DEFAULT_IMAGE_HANDLE}; | ||
|
|
||
| /// The sprite texture |
There was a problem hiding this comment.
These docs are not useful to users who do not know what a sprite is.
|
|
||
| /// The sprite texture | ||
| #[derive(Component, Clone, Debug, Reflect)] | ||
| pub enum SpriteImage { |
There was a problem hiding this comment.
Perhaps just Sprite? I'm curious about others opinion here.
There was a problem hiding this comment.
Well Sprite is already a component
|
We should run some of the 2D stress tests before and after this PR. Ideally we also put together a texture-atlas stress test in some form too. We are introducing a branch, so I would expect to see some performance regression, but it may be very small in practice. On the plus side this would make swapping an entity between a single sprite and a sprite sheet much faster because there's no components being added and removed. I can't imagine that happens much though in practice? |
e94650f to
04308a0
Compare
|
I'm not sure I like having to add those |
I get that, and the enum approach adds some abstraction that prevents querying directly for Note that you already have to call Either way I think its a choice between:
But I do like the enum wrapper as it removes redundancy, but maybe there is a better way |
|
Closing in favor of #5103. |
# Objective > Old MR: #5072 > ~~Associated UI MR: #5070~~ > Adresses #1618 Unify sprite management ## Solution - Remove the `Handle<Image>` field in `TextureAtlas` which is the main cause for all the boilerplate - Remove the redundant `TextureAtlasSprite` component - Renamed `TextureAtlas` asset to `TextureAtlasLayout` ([suggestion](#5103 (comment))) - Add a `TextureAtlas` component, containing the atlas layout handle and the section index The difference between this solution and #5072 is that instead of the `enum` approach is that we can more easily manipulate texture sheets without any breaking changes for classic `SpriteBundle`s (@mockersf [comment](#5072 (comment))) Also, this approach is more *data oriented* extracting the `Handle<Image>` and avoiding complex texture atlas manipulations to retrieve the texture in both applicative and engine code. With this method, the only difference between a `SpriteBundle` and a `SpriteSheetBundle` is an **additional** component storing the atlas handle and the index. ~~This solution can be applied to `bevy_ui` as well (see #5070).~~ EDIT: I also applied this solution to Bevy UI ## Changelog - (**BREAKING**) Removed `TextureAtlasSprite` - (**BREAKING**) Renamed `TextureAtlas` to `TextureAtlasLayout` - (**BREAKING**) `SpriteSheetBundle`: - Uses a `Sprite` instead of a `TextureAtlasSprite` component - Has a `texture` field containing a `Handle<Image>` like the `SpriteBundle` - Has a new `TextureAtlas` component instead of a `Handle<TextureAtlasLayout>` - (**BREAKING**) `DynamicTextureAtlasBuilder::add_texture` takes an additional `&Handle<Image>` parameter - (**BREAKING**) `TextureAtlasLayout::from_grid` no longer takes a `Handle<Image>` parameter - (**BREAKING**) `TextureAtlasBuilder::finish` now returns a `Result<(TextureAtlasLayout, Handle<Image>), _>` - `bevy_text`: - `GlyphAtlasInfo` stores the texture `Handle<Image>` - `FontAtlas` stores the texture `Handle<Image>` - `bevy_ui`: - (**BREAKING**) Removed `UiAtlasImage` , the atlas bundle is now identical to the `ImageBundle` with an additional `TextureAtlas` ## Migration Guide * Sprites ```diff fn my_system( mut images: ResMut<Assets<Image>>, - mut atlases: ResMut<Assets<TextureAtlas>>, + mut atlases: ResMut<Assets<TextureAtlasLayout>>, asset_server: Res<AssetServer> ) { let texture_handle: asset_server.load("my_texture.png"); - let layout = TextureAtlas::from_grid(texture_handle, Vec2::new(25.0, 25.0), 5, 5, None, None); + let layout = TextureAtlasLayout::from_grid(Vec2::new(25.0, 25.0), 5, 5, None, None); let layout_handle = atlases.add(layout); commands.spawn(SpriteSheetBundle { - sprite: TextureAtlasSprite::new(0), - texture_atlas: atlas_handle, + atlas: TextureAtlas { + layout: layout_handle, + index: 0 + }, + texture: texture_handle, ..Default::default() }); } ``` * UI ```diff fn my_system( mut images: ResMut<Assets<Image>>, - mut atlases: ResMut<Assets<TextureAtlas>>, + mut atlases: ResMut<Assets<TextureAtlasLayout>>, asset_server: Res<AssetServer> ) { let texture_handle: asset_server.load("my_texture.png"); - let layout = TextureAtlas::from_grid(texture_handle, Vec2::new(25.0, 25.0), 5, 5, None, None); + let layout = TextureAtlasLayout::from_grid(Vec2::new(25.0, 25.0), 5, 5, None, None); let layout_handle = atlases.add(layout); commands.spawn(AtlasImageBundle { - texture_atlas_image: UiTextureAtlasImage { - index: 0, - flip_x: false, - flip_y: false, - }, - texture_atlas: atlas_handle, + atlas: TextureAtlas { + layout: layout_handle, + index: 0 + }, + image: UiImage { + texture: texture_handle, + flip_x: false, + flip_y: false, + }, ..Default::default() }); } ``` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: François <mockersf@gmail.com> Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
Related PR: #5070 (bevy_ui support for texture sheets)
Objective
Improve ergonomics for sprite sheets and remove:
SpriteSheetBundleTextureAtlasSpritewhich is almost identic toSpriteDev side, this will improve maintenance and avoid duplicate queries and systems for sprite sheets
Solution
I replaced the
SpriteBundle::texturefield , aHandle<Image>, by a customSpriteImageenum which can store either:Handle<Image>Handle<TextureAtlas>and texture sheetindexTasks:
SpriteImageChangelog
SpriteBundlenow takes aSpriteImageinstead of aHandle<Image>SpriteSheetBundleTextureAtlasSpritecomponentMigration Guide
Sprites
let handle = asset_server.load("my_icon.png"); commands.spawn_bundle(SpriteBundle { - texture: handle, + texture: handle.into(), ..default() });or
let handle = asset_server.load("my_icon.png"); commands.spawn_bundle(SpriteBundle { - texture: handle, + texture: SpriteImage::Image(handle), ..default() });Sprite sheets
Before:
after: