Remove Need for Sprite Size Sync System (#2632)

# Objective

- Prevent the need to have a system that synchronizes sprite sizes with their images

## Solution

- Read the sprite size from the image asset when rendering the sprite
- Replace the `size` and `resize_mode` fields of `Sprite` with a `custom_size: Option<Vec2>` that will modify the sprite's rendered size to be different than the image size, but only if it is `Some(Vec2)`
This commit is contained in:
Zicklag 2021-08-26 00:53:51 +00:00
parent dd32cd029d
commit cea7db1050
4 changed files with 17 additions and 68 deletions

View file

@ -3,10 +3,10 @@ use bevy::{
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
ecs::prelude::*,
input::Input,
math::{Vec2, Vec3},
math::Vec3,
prelude::{App, AssetServer, Handle, MouseButton, Transform},
render2::{camera::OrthographicCameraBundle, color::Color, texture::Image},
sprite2::{PipelinedSpriteBundle, Sprite},
sprite2::PipelinedSpriteBundle,
window::WindowDescriptor,
PipelinedDefaultPlugins,
};
@ -177,10 +177,6 @@ fn spawn_birds(
.spawn_bundle(PipelinedSpriteBundle {
// material: bird_material.0.clone(),
texture: texture.clone(),
sprite: Sprite {
size: Vec2::new(250.0, 250.0),
..Default::default()
},
transform: Transform {
translation: Vec3::new(bird_x, bird_y, bird_z),
scale: Vec3::splat(BIRD_SCALE),

View file

@ -25,9 +25,7 @@ pub struct SpritePlugin;
impl Plugin for SpritePlugin {
fn build(&self, app: &mut App) {
app.add_asset::<TextureAtlas>()
.register_type::<Sprite>()
.add_system_to_stage(CoreStage::PostUpdate, sprite_auto_resize_system);
app.add_asset::<TextureAtlas>().register_type::<Sprite>();
let render_app = app.sub_app(RenderApp);
render_app
.init_resource::<ExtractedSprites>()

View file

@ -190,16 +190,21 @@ pub fn extract_sprites(
) {
let mut extracted_sprites = Vec::new();
for (sprite, transform, handle) in sprite_query.iter() {
if !images.contains(handle) {
let image = if let Some(image) = images.get(handle) {
image
} else {
continue;
}
};
let size = image.texture_descriptor.size;
extracted_sprites.push(ExtractedSprite {
atlas_size: None,
transform: transform.compute_matrix(),
rect: Rect {
min: Vec2::ZERO,
max: sprite.size,
max: sprite
.custom_size
.unwrap_or_else(|| Vec2::new(size.width as f32, size.height as f32)),
},
handle: handle.clone_weak(),
});

View file

@ -1,65 +1,15 @@
use bevy_asset::{Assets, Handle};
use bevy_ecs::prelude::{Query, Res};
use bevy_math::Vec2;
use bevy_reflect::{Reflect, ReflectDeserialize, TypeUuid};
use bevy_render2::texture::Image;
use serde::{Deserialize, Serialize};
use bevy_reflect::{Reflect, TypeUuid};
#[derive(Debug, Default, Clone, TypeUuid, Reflect)]
#[uuid = "7233c597-ccfa-411f-bd59-9af349432ada"]
#[repr(C)]
pub struct Sprite {
pub size: Vec2,
/// Flip the sprite along the X axis
pub flip_x: bool,
/// Flip the sprite along the Y axis
pub flip_y: bool,
pub resize_mode: SpriteResizeMode,
}
/// Determines how `Sprite` resize should be handled
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
#[reflect_value(PartialEq, Serialize, Deserialize)]
pub enum SpriteResizeMode {
Manual,
Automatic,
}
impl Default for SpriteResizeMode {
fn default() -> Self {
SpriteResizeMode::Automatic
}
}
impl Sprite {
/// Creates new `Sprite` with `SpriteResizeMode::Manual` value for `resize_mode`
pub fn new(size: Vec2) -> Self {
Self {
size,
resize_mode: SpriteResizeMode::Manual,
flip_x: false,
flip_y: false,
}
}
}
/// System that resizes sprites that have their resize mode set to automatic
pub fn sprite_auto_resize_system(
textures: Res<Assets<Image>>,
mut query: Query<(&mut Sprite, &Handle<Image>)>,
) {
for (mut sprite, image_handle) in query.iter_mut() {
match sprite.resize_mode {
SpriteResizeMode::Manual => continue,
SpriteResizeMode::Automatic => {
if let Some(image) = textures.get(image_handle) {
let extent = image.texture_descriptor.size;
let texture_size = Vec2::new(extent.width as f32, extent.height as f32);
// only set sprite size if it has changed (this check prevents change
// detection from triggering)
if sprite.size != texture_size {
sprite.size = texture_size;
}
}
}
}
}
/// An optional custom size for the sprite that will be used when rendering, instead of the size
/// of the sprite's image
pub custom_size: Option<Vec2>,
}