Nodes added into scene tree in script are not visible

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By noemi

Hello,

I’m having difficulty figuring out why some instanced nodes that are being programmatically instanced and added to the scene tree using a managing “menu” node are not visible in-game. For context, these nodes are part of a targeting menu that is being used to allow the player to select a cell in the grid-based map to perform actions on, i.e. attacking.

Things I’ve checked and made sure of:

  • The nodes have a visible Sprite2D child that has the desired texture attached
  • The nodes, the manager, and all prior parent nodes have visibility set to true
  • The manager is a child of the player node, which is appearing correctly
  • When manually adding the nodes in the editor they appear as they should be
  • Checking the Remote tree in the debugger using a breakpoint, the nodes are being added as children of the manager with the correct position data. By all accounts they should be showing up right next to the player
  • Zooming out with the camera, they don’t seem to be placed anywhere else on the map, so in tandem with my debugging checks I feel pretty confident it’s not a positioning error

The code is incomplete but it should be at the point where it displays the cells.

Manager Code:

extends Node2D

@onready var player = get_parent()
@onready var map = player.map
var cell_model = preload("res://maps/targeting_cell.tscn")
var mode = null
var cell_idx = 0

func activate_targeting(action_range, mode):
	var player_cell = player.map_coords
	var adjacent_cells = player.adjacent_cells()
	self.mode = mode
	for x in range(1, action_range+1):
		for cell in adjacent_cells:
			var cell_offset = cell * x
			var cell_node = cell_model.instantiate()
			cell_node.coords = player_cell + cell_offset
			cell_node.inhabitant = map.being_at_coords(cell_node.coords)
			add_child(cell_node)
			cell_node.position = Vector2(cell_offset * 16)
	activate_cell()
	
func deactivate_targeting():
	mode = null
	for n in get_children():
		n.queue_free()
	
func activate_cell():
	get_child(cell_idx).select()
	
func deactivate_cell():
	get_child(cell_idx).unselect()
	
func up():
	deactivate_cell()
	cell_idx = (cell_idx - 1) % get_child_count()
	activate_cell()
	
func down():
	deactivate_cell()
	cell_idx = (cell_idx - 1) % get_child_count()
	activate_cell()

func left():
	up()
	
func right():
	down()
	
func select():
	var selection = get_child(cell_idx)
	deactivate_targeting()

Target Cell Node:

extends Node2D

var colors = {
	"unselected": Color(1, 1, 1),
	"selected": Color(0, 1, 0)
}
var coords = Vector2i(0, 0)
var inhabitant = null

func select():
	modulate = colors["selected"]
	
func unselect():
	modulate = colors["unselected"]

Let me know if any additional context is needed. I have my map, player, etc. as children of a SubViewport in a SubViewportContainer if that helps.

:bust_in_silhouette: Reply From: aidave

Try playing with the ordering of:

        add_child(cell_node)
        cell_node.position = Vector2(cell_offset * 16)

Reversing that.

Other things to try are cell_node.visible = true and setting global_position instead.

Poll the position/global_position by printing them and see if that’s the cause