Is there any way to scale up a NinePatchRect (without actually scaling the node)?

I’ve been struggling a bit with this. Is there a simple way to scale up the borders of a NinePatchRect without scaling the actual node?

I have a 16x16 rect, but the actual game is in high resolution. The resulting NinePatchRect has tiny borders.

I want to avoid scaling up the ninepatchrect itself since that makes anchoring annoying, and any child would be scaled up as well.

Yes. Editing the texture you use. :wink: From Godot itself? No.

Ran into the same problem and haven’t found anyone else with a better solution at the moment, so I decided to write something to solve this.

Add a Container and add this script to it:

@tool
class_name TileScaleContainer
extends Container

@export var tile_scale: float = 1:
	set(value):
		tile_scale = value
		_resize_children()
		
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	_resize_children()

func _notification(what: int) -> void:
	match what:
		NOTIFICATION_RESIZED:
			_resize_children()

func _on_child_entered_tree(node: Node):
	_resize_child(node)
	
func _resize_child(node: Node):
	if "size" in node and "scale" in node:
		node.size = size if tile_scale == 0 else Vector2(size.x / tile_scale, size.y / tile_scale)
		node.scale = Vector2(1, 1) if tile_scale == 0 else Vector2(tile_scale, tile_scale)


func _resize_children():
	for node in get_children():
		_resize_child(node)

Now when you add children to this container (ie. NinePatchRect, or a Button using a StyleBoxTexture with texture margins) and change the “tile_scale”, the “tile_scale” will control the scale of the border.

Changing the size of the TileScaleContainer will maintain the same border size now as well.

1 Like