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

Can't change nine patch textureΒ #2

@Hugheth

Description

@Hugheth

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());
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions