Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Can't change nine patch texture #2

Open
Hugheth opened this issue Dec 23, 2020 · 3 comments
Open

Can't change nine patch texture #2

Hugheth opened this issue Dec 23, 2020 · 3 comments

Comments

@Hugheth
Copy link

Hugheth commented Dec 23, 2020

Is there an easy way to change the texture of the nine patch?

I'm trying to make a UI button which has nine patch states for normal, hover & pressed

Here are the things I've tried:

  1. Changing the nine_patch_data.texture in a system but this doesn't appear to work
  2. Using despawn(nine_patch_bundle) but this doesn't remove the child objects
  3. Using despawn_recursive, but then spawning a new NinePatchBundle under the same parent (a ButtonBundle) doesn't result in it getting drawn, not sure why?

I'm also finding after (3.) is run a number of times, my FPS grinds quickly down to a few frames a second.

Do you have any tips on debugging / improving the performance of the UI? Perhaps I can cache the 3 nine patches I need for the button in some way? Still very new to Bevy!

Great tool, very excited to be trying it out 😄

Here's what I'm toying with:

use bevy::prelude::*;
use bevy_ninepatch::*;

pub struct ButtonResource {
	option: Option<ButtonTextures>,
}

impl FromResources for ButtonResource {
	fn from_resources(_resources: &Resources) -> Self {
		ButtonResource { option: None }
	}
}

pub struct ButtonTextures {
	pub normal: Handle<Texture>,
	pub hover: Handle<Texture>,
	pub pressed: Handle<Texture>,
}

pub fn button_system(
	commands: &mut Commands,
	button_resource: Res<ButtonResource>,
	mut nine_patches: ResMut<Assets<NinePatchBuilder<()>>>,
	mut interaction_query: Query<
		(Entity, &Interaction, &Children),
		(Mutated<Interaction>, With<Button>),
	>,
) {
	if let Some(textures) = &button_resource.option {
		for (entity, interaction, children) in interaction_query.iter_mut() {
			if let Some(child) = children.get(0) {
				commands.despawn_recursive(*child);
				let texture = match *interaction {
					Interaction::Clicked => textures.pressed.clone(),
					Interaction::Hovered => textures.hover.clone(),
					Interaction::None => textures.normal.clone(),
				};
				let nine_patch = nine_patches.add(NinePatchBuilder::by_margins(20, 20, 20, 20));
				let nine_patch_data = NinePatchData {
					texture,
					nine_patch,
					..Default::default()
				};
				commands
					.spawn(NinePatchBundle {
						nine_patch_data,
						..Default::default()
					})
					.with(Parent(entity));
			}
		}
	}
}

pub fn setup_buttons(
	commands: &mut Commands,
	mut button_textures: ResMut<ButtonResource>,
	asset_server: Res<AssetServer>,
	mut materials: ResMut<Assets<ColorMaterial>>,
	mut nine_patches: ResMut<Assets<NinePatchBuilder<()>>>,
) {
	let normal = asset_server.load("button.png");
	let nine_patch = nine_patches.add(NinePatchBuilder::by_margins(20, 20, 20, 20));
	button_textures.option = Some(ButtonTextures {
		normal: normal.clone(),
		hover: asset_server.load("button-hover.png"),
		pressed: asset_server.load("button-pressed.png"),
	});
	commands
		.spawn(ButtonBundle {
			material: materials.add(Color::NONE.into()),
			style: Style {
				size: Size::new(Val::Px(100.), Val::Px(32.)),
				margin: Rect::all(Val::Auto),
				justify_content: JustifyContent::Center,
				align_items: AlignItems::Center,
				..Default::default()
			},
			..Default::default()
		})
		.with_children(|parent| {
			let nine_patch_data = NinePatchData {
				texture: normal,
				nine_patch,
				..Default::default()
			};
			parent.spawn(NinePatchBundle {
				style: Style {
					size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
					..Default::default()
				},
				nine_patch_data,
				..Default::default()
			});
		})
		.current_entity()
		.unwrap();

	commands.spawn(CameraUiBundle::default());
}
@mockersf mockersf transferred this issue from vleue/bevy_easings Feb 14, 2022
@VincentDouchin
Copy link

I am encountering the same problem, is there a way to do this?

@vladim0105
Copy link

vladim0105 commented Jun 3, 2023

I am encountering the same problem, is there a way to do this?

ATM no, but there is a workaround:

You could have 3 node bundles each containing the nine patch with the right texture, and then set the display property accordingly...

...but by doing this I am experiencing a weird bug where the nine patches are all square in size, even though I set different width and height

@VincentDouchin
Copy link

Yeah that's what I figured, I might do this in the future, thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants