How to make Node2Ds equal in size?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jarlowrey
:warning: Old Version Published before Godot 3 was released.

So Node2Ds have a Scale property, but no global width/height (as far as I can see). How can I ensure 2 Node2Ds have the same global width/height? It seems like you’d have to find the texture size, transform from local to global, and then back to local space to set the new scale properties, but that seems like a lot of boilerplate stuff for a simple function.

Sprite with a CollisionShape2D that should perfectly overlap (preferably thru code and not resizing in the editor).

enter image description here

Edit: @eons helped me find the answer in the comments below:

func resize_to(ref, resizable):
    var size = ref.get_item_rect().size
    var pos = -size/2
    resizable.edit_set_rect(Rect2(pos,size))
:bust_in_silhouette: Reply From: eons

Well, that “simple function” is absent from many engines, even the pixel based ones, is not that simple in practice [insert Boromir meme here].

Also the implementation changes in every case, in the image, you don’t want the hitbox of the same size of the sprite, and the sprite not centered that way.


Some general approach I take is:

main object
|-Visual representation
|-hitbox

Sometimes you can get the visual representation size, usually not, use the image size/frames in that case (in most cases, you already know the size of everything).

When scaling, scale the visual part, the hitbox almost never gets correctly aligned if scaled, is better to take the scale into account and resize it and correct the offset.

In the case of Godot, the Sprite can have an offset saving the problem of body shape resize offset (also less headaches with main rotations that way).

ps: the Physics server does not like much the scaling of bodies (and some shapes) so is another reason to scale just what needs to be scaled.

Hmmm alright then sounds more difficult than I imagined. If it must be implemented on a case-by-case basis, is there a way to get a node’s global width/height in the Godot API? Thanks for responding!

jarlowrey | 2017-05-04 15:06

Looks like textures have a Size (x,y) property that should do it. So from Sprites access the texture and scale it by the sprites scale and apply to the new sprite. Thanks @eons!

jarlowrey | 2017-05-04 15:12

CanvasItems have a kind of boundary you can get with get_item_rect , but it is bigger than the area of nodes that have some drawing implemented, can be used as reference in some situations.

eons | 2017-05-04 15:35

Hey cool thanks! I originally had this

func resize_shape(ref_sprite, rect_shape_2D):
	var size = ref_sprite.get_texture().get_size() * ref_sprite.get_scale()
	rect_shape_2D.get_shape().set_extents(size/2)

But with your suggestion modified it to the more general code below:

func resize_to(ref, resizable):
	var size = ref.get_item_rect().size
	var pos = -size/2
	resizable.edit_set_rect(Rect2(pos,size))

And it works great!

enter image description here

jarlowrey | 2017-05-04 15:57

Nice! that may work with sprites with many frames too (if are compact).

eons | 2017-05-04 17:20