TexturedRect created via EditorScript does not update anchor position on creation

Godot Version

4.5.1

Question

When creating a TextureRect node via EditorScript, it doesn’t set the position to the correct value. The moment I use the move tool, it snaps to the correct position.
The only way to fix it is to select the sprite and move it with the move tool, which automatically snaps to the correct position. (however, when I set the size of the node, it doesnt snap to center with the move tool)

Is this a bug or I did something wrong with my code?

func load_character(sprite_path: String) -> void:
	var split = sprite_path.split("/")
	var name = split[-1].split(".")[0]
	
	var node = TextureRect.new()
	var texture: Texture2D = load(sprite_path)
	node.set_name(name)
	node.set_texture(texture)
	node.custom_minimum_size = texture.get_size()
	
	node.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
	
	var parent = get_scene()
	
	node.set_anchors_preset(Control.PRESET_CENTER_BOTTOM, true)
	
	parent.add_child(node)
	node.owner = get_scene()


EDIT: Found a solution added at bottom of this post!

I tried really hard to recreate this as I thought I had an answer, but I could not get my generated texture rect to position itself with set_anchors_preset either.

My example texture rect for comparison with anchors set in the editor gave a global position of (499.0, 544.0) which was positioned correctly. The generated texture rect kept giving a global position of (499.0, 544.0). It was like the layout mode was set to position and not anchors. But you cannot change this in code, only in the inspector.

Anyway, it works fine if you have a pre-existing margin container set in the editor to anchor center bottom, and then just generate a texture into that without trying to set its anchors. Perhaps not a solution but a work around would be to put your character into a pre-existing container. (Although I can imagine plenty of reasons this might not be possible). It looks like you are doing a dialogue system so this might work for you.

I hope someone else can shed some light on this.

PS I used a canvas layer, with a child control node set to full screen, and tried to generate a texture rect center bottom within that set up. I got the same problem with the anchor mode for the rect being set to top_left still, instead of center_bottom

PPS It’s a bit silly, but doing this after add_child for the texture rect without a pre-existing container got it back to the right position.

	node.position.x = node.position.x - node.get_size().x / 2
	node.position.y = node.position.y - node.get_size().y

PPPS
Setting these things manually worked as well (Sorry to double post).

	var texture_size = node.texture.get_size()
	node.anchor_left = 0.5
	node.anchor_right = 0.5
	node.anchor_top = 1.0
	node.anchor_bottom = 1.0
	node.offset_left = -texture_size.x / 2
	node.offset_right = texture_size.x / 2
	node.offset_top = -texture_size.y
	node.offset_bottom = 0
	control.add_child(node)

FINALLY (30 mins of trying everything and anything later):
This worked:

	node.set_anchors_preset(Control.PRESET_CENTER_BOTTOM, true)
	node.set_offsets_preset(Control.PRESET_CENTER_BOTTOM)
2 Likes

Hey, thanks for the reply.

I’m very sorry for the late reply because i did not receive any notification via email.

Since you said the following below worked, is it necessary to have the top code you shown before to work?

node.set_anchors_preset(Control.PRESET_CENTER_BOTTOM, true)
node.set_offsets_preset(Control.PRESET_CENTER_BOTTOM)

By top code, I meant this code:

var texture_size = node.texture.get_size()
node.anchor_left = 0.5
node.anchor_right = 0.5
node.anchor_top = 1.0
node.anchor_bottom = 1.0
node.offset_left = -texture_size.x / 2
node.offset_right = texture_size.x / 2
node.offset_top = -texture_size.y
node.offset_bottom = 0
control.add_child(node)
1 Like