Skip to content

Yet another Migrate bevy_sprite to required components #15562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions crates/bevy_ecs/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ use core::{any::TypeId, ptr::NonNull};
/// Additionally, [Tuples](`tuple`) of bundles are also [`Bundle`] (with up to 15 bundles).
/// These bundles contain the items of the 'inner' bundles.
/// This is a convenient shorthand which is primarily used when spawning entities.
/// For example, spawning an entity using the bundle `(SpriteBundle {...}, PlayerMarker)`
/// will spawn an entity with components required for a 2d sprite, and the `PlayerMarker` component.
///
/// [`unit`], otherwise known as [`()`](`unit`), is a [`Bundle`] containing no components (since it
/// can also be considered as the empty tuple).
Expand Down
14 changes: 9 additions & 5 deletions crates/bevy_sprite/src/bundle.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::Sprite;
use bevy_asset::Handle;
#![expect(deprecated)]

use crate::{Sprite, SpriteProperties};
use bevy_ecs::bundle::Bundle;
use bevy_render::{
texture::Image,
view::{InheritedVisibility, ViewVisibility, Visibility},
world_sync::SyncToRenderWorld,
};
Expand All @@ -16,15 +16,19 @@ use bevy_transform::components::{GlobalTransform, Transform};
/// - [`ImageScaleMode`](crate::ImageScaleMode) to enable either slicing or tiling of the texture
/// - [`TextureAtlas`](crate::TextureAtlas) to draw a specific section of the texture
#[derive(Bundle, Clone, Debug, Default)]
#[deprecated(
since = "0.15.0",
note = "Use the `Sprite` component instead. Inserting them will now also insert the other components required by them automatically."
)]
pub struct SpriteBundle {
/// Specifies the rendering properties of the sprite, such as color tint and flip.
pub sprite: Sprite,
pub sprite: SpriteProperties,
/// The local transform of the sprite, relative to its parent.
pub transform: Transform,
/// The absolute transform of the sprite. This should generally not be written to directly.
pub global_transform: GlobalTransform,
/// A reference-counted handle to the image asset to be drawn.
pub texture: Handle<Image>,
pub texture: Sprite,
/// User indication of whether an entity is visible
pub visibility: Visibility,
/// Inherited visibility of an entity.
Expand Down
34 changes: 18 additions & 16 deletions crates/bevy_sprite/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub mod prelude {
#[doc(hidden)]
pub use crate::{
bundle::SpriteBundle,
sprite::{ImageScaleMode, Sprite},
sprite::{ImageScaleMode, Sprite, SpriteProperties},
texture_atlas::{TextureAtlas, TextureAtlasLayout, TextureAtlasSources},
texture_slice::{BorderRect, SliceScaleMode, TextureSlice, TextureSlicer},
ColorMaterial, ColorMesh2dBundle, MeshMaterial2d, TextureAtlasBuilder,
Expand Down Expand Up @@ -85,9 +85,9 @@ pub enum SpriteSystem {
#[reflect(Component, Default, Debug)]
pub struct SpriteSource;

/// A convenient alias for `Or<With<Sprite>, With<SpriteSource>>`, for use with
/// A convenient alias for `Or<With<SpriteProperties>, With<SpriteSource>>`, for use with
/// [`bevy_render::view::VisibleEntities`].
pub type WithSprite = Or<(With<Sprite>, With<SpriteSource>)>;
pub type WithSprite = Or<(With<SpriteProperties>, With<SpriteSource>)>;

impl Plugin for SpritePlugin {
fn build(&self, app: &mut App) {
Expand All @@ -106,6 +106,7 @@ impl Plugin for SpritePlugin {
app.init_asset::<TextureAtlasLayout>()
.register_asset_reflect::<TextureAtlasLayout>()
.register_type::<Sprite>()
.register_type::<SpriteProperties>()
.register_type::<ImageScaleMode>()
.register_type::<TextureSlicer>()
.register_type::<Anchor>()
Expand Down Expand Up @@ -174,7 +175,7 @@ impl Plugin for SpritePlugin {

/// System calculating and inserting an [`Aabb`] component to entities with either:
/// - a `Mesh2d` component,
/// - a `Sprite` and `Handle<Image>` components,
/// - a `SpriteProperties` and `Sprite` components,
/// and without a [`NoFrustumCulling`] component.
///
/// Used in system set [`VisibilitySystems::CalculateBounds`].
Expand All @@ -185,9 +186,13 @@ pub fn calculate_bounds_2d(
atlases: Res<Assets<TextureAtlasLayout>>,
meshes_without_aabb: Query<(Entity, &Mesh2d), (Without<Aabb>, Without<NoFrustumCulling>)>,
sprites_to_recalculate_aabb: Query<
(Entity, &Sprite, &Handle<Image>, Option<&TextureAtlas>),
(Entity, &SpriteProperties, &Sprite, Option<&TextureAtlas>),
(
Or<(Without<Aabb>, Changed<Sprite>, Changed<TextureAtlas>)>,
Or<(
Without<Aabb>,
Changed<SpriteProperties>,
Changed<TextureAtlas>,
)>,
Without<NoFrustumCulling>,
),
>,
Expand Down Expand Up @@ -259,10 +264,7 @@ mod test {
app.add_systems(Update, calculate_bounds_2d);

// Add entities
let entity = app
.world_mut()
.spawn((Sprite::default(), image_handle))
.id();
let entity = app.world_mut().spawn(Sprite(image_handle)).id();

// Verify that the entity does not have an AABB
assert!(!app
Expand Down Expand Up @@ -303,11 +305,11 @@ mod test {
let entity = app
.world_mut()
.spawn((
Sprite {
Sprite(image_handle),
SpriteProperties {
custom_size: Some(Vec2::ZERO),
..default()
},
image_handle,
))
.id();

Expand All @@ -328,8 +330,8 @@ mod test {
.get_entity_mut(entity)
.expect("Could not find entity");
let mut sprite = binding
.get_mut::<Sprite>()
.expect("Could not find sprite component of entity");
.get_mut::<SpriteProperties>()
.expect("Could not find sprite property component of entity");
sprite.custom_size = Some(Vec2::ONE);

// Re-run the `calculate_bounds_2d` system to get the new AABB
Expand Down Expand Up @@ -368,12 +370,12 @@ mod test {
let entity = app
.world_mut()
.spawn((
Sprite {
Sprite(image_handle),
SpriteProperties {
rect: Some(Rect::new(0., 0., 0.5, 1.)),
anchor: Anchor::TopRight,
..default()
},
image_handle,
))
.id();

Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_sprite/src/picking_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use core::cmp::Reverse;

use crate::{Sprite, TextureAtlas, TextureAtlasLayout};
use crate::{Sprite, SpriteProperties, TextureAtlas, TextureAtlasLayout};
use bevy_app::prelude::*;
use bevy_asset::prelude::*;
use bevy_ecs::prelude::*;
Expand All @@ -31,9 +31,9 @@ pub fn sprite_picking(
texture_atlas_layout: Res<Assets<TextureAtlasLayout>>,
sprite_query: Query<(
Entity,
&Sprite,
&SpriteProperties,
Option<&TextureAtlas>,
&Handle<Image>,
&Sprite,
&GlobalTransform,
Option<&PickingBehavior>,
&ViewVisibility,
Expand Down
24 changes: 16 additions & 8 deletions crates/bevy_sprite/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use core::ops::Range;

use crate::{
texture_atlas::{TextureAtlas, TextureAtlasLayout},
ComputedTextureSlices, Sprite, WithSprite, SPRITE_SHADER_HANDLE,
ComputedTextureSlices, Sprite, SpriteProperties, WithSprite, SPRITE_SHADER_HANDLE,
};
use bevy_asset::{AssetEvent, AssetId, Assets, Handle};
use bevy_asset::{AssetEvent, AssetId, Assets};
use bevy_color::{ColorToComponents, LinearRgba};
use bevy_core_pipeline::{
core_2d::{Transparent2d, CORE_2D_DEPTH_FORMAT},
Expand Down Expand Up @@ -375,17 +375,25 @@ pub fn extract_sprites(
Entity,
&RenderEntity,
&ViewVisibility,
&Sprite,
&SpriteProperties,
&GlobalTransform,
&Handle<Image>,
&Sprite,
Option<&TextureAtlas>,
Option<&ComputedTextureSlices>,
)>,
>,
) {
extracted_sprites.sprites.clear();
for (original_entity, entity, view_visibility, sprite, transform, handle, sheet, slices) in
sprite_query.iter()
for (
original_entity,
entity,
view_visibility,
sprite,
transform,
sprite_texture,
sheet,
slices,
) in sprite_query.iter()
{
if !view_visibility.get() {
continue;
Expand All @@ -394,7 +402,7 @@ pub fn extract_sprites(
if let Some(slices) = slices {
extracted_sprites.sprites.extend(
slices
.extract_sprites(transform, original_entity, sprite, handle)
.extract_sprites(transform, original_entity, sprite, sprite_texture)
.map(|e| (commands.spawn(TemporaryRenderEntity).id(), e)),
);
} else {
Expand Down Expand Up @@ -423,7 +431,7 @@ pub fn extract_sprites(
custom_size: sprite.custom_size,
flip_x: sprite.flip_x,
flip_y: sprite.flip_y,
image_handle_id: handle.id(),
image_handle_id: sprite_texture.id(),
anchor: sprite.anchor.as_vec(),
original_entity: Some(original_entity),
},
Expand Down
56 changes: 51 additions & 5 deletions crates/bevy_sprite/src/sprite.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
use bevy_asset::{AssetId, Handle};
use bevy_color::Color;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{component::Component, reflect::ReflectComponent};
use bevy_math::{Rect, Vec2};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::{texture::Image, view::Visibility, world_sync::SyncToRenderWorld};
use bevy_transform::components::Transform;

use crate::TextureSlicer;

/// Specifies the rendering properties of a sprite.
///
/// This is commonly used as a component within [`SpriteBundle`](crate::bundle::SpriteBundle).
#[derive(Component, Debug, Default, Clone, Reflect)]
#[reflect(Component, Default, Debug)]
pub struct Sprite {
pub struct SpriteProperties {
/// The sprite's color tint
pub color: Color,
/// Flip the sprite along the `X` axis
Expand All @@ -30,10 +33,10 @@ pub struct Sprite {
pub anchor: Anchor,
}

impl Sprite {
impl SpriteProperties {
/// Create a Sprite with a custom size
pub fn sized(custom_size: Vec2) -> Self {
Sprite {
SpriteProperties {
custom_size: Some(custom_size),
..Default::default()
}
Expand All @@ -58,7 +61,7 @@ pub enum ImageScaleMode {
},
}

/// How a sprite is positioned relative to its [`Transform`](bevy_transform::components::Transform).
/// How a sprite is positioned relative to its [`Transform`].
/// It defaults to `Anchor::Center`.
#[derive(Component, Debug, Clone, Copy, PartialEq, Default, Reflect)]
#[reflect(Component, Default, Debug, PartialEq)]
Expand Down Expand Up @@ -95,3 +98,46 @@ impl Anchor {
}
}
}

/// A component for rendering sprites.
///
/// # Example
///
/// ```ignore
/// # use bevy_ecs::prelude::*;
/// # use bevy_render::texture::Image;
/// # use bevy_asset::{AssetServer, Assets};
/// #
/// // Spawn an entity with a sprite.
/// fn setup(
/// mut commands: Commands,
/// mut images: ResMut<Assets<Image>>,
/// asset_server: Res<AssetServer>
/// ) {
/// commands.spawn((
/// Sprite(images.add(Image::default())),
/// ));
/// }
/// ```
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]
#[reflect(Component, Default)]
#[require(SpriteProperties, Transform, Visibility, SyncToRenderWorld)]
pub struct Sprite(pub Handle<Image>);

impl From<Handle<Image>> for Sprite {
fn from(handle: Handle<Image>) -> Self {
Self(handle)
}
}

impl From<Sprite> for AssetId<Image> {
fn from(texture: Sprite) -> Self {
texture.id()
}
}

impl From<&Sprite> for AssetId<Image> {
fn from(texture: &Sprite) -> Self {
texture.id()
}
}
2 changes: 1 addition & 1 deletion crates/bevy_sprite/src/texture_atlas_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl<'a> TextureAtlasBuilder<'a> {
/// let layout = layouts.add(atlas_layout);
/// // Spawn your sprite
/// commands.spawn((
/// SpriteBundle { texture, ..Default::default() },
/// Sprite(texture),
/// TextureAtlas::from(layout),
/// ));
/// }
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_sprite/src/texture_slice/border_rect.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy_reflect::Reflect;

/// Struct defining a [`Sprite`](crate::Sprite) border with padding values
/// Struct defining a [`SpriteProperties`](crate::SpriteProperties) border with padding values
#[derive(Default, Copy, Clone, PartialEq, Debug, Reflect)]
pub struct BorderRect {
/// Pixel padding to the left
Expand Down
Loading