trying to have an image appear when clicking on a character

hi i’m new to programming/coding. i’m trying to do simple things to slowly build up what kind of game i want to create, which is a small tactical rpg/deck builder

i used this tutorial (and this github with godot4 version) as a basis for my game concept. what i want to do is, when i click on a unit, i’d like for an image to appear, specifically i have a card image that i’d like to show up. eventually i want to replace it with an actual menu. i thought this might be simple for a beginner but perhaps not..

my knowledge on gdscript is still not great. i have tried using signals to have the image, or well node, appear, so for example, the card only appears when the unit is in a selected state, but i could never get it to work (i got frustrated and erased my code…), but i’m wondering if there is a simpler way that does not require me to use signals just to have a node appear when clicking on a unit, or if there something that may help me better understand signals

right now i have a card on the actual game. i can hide it from view with the hide() function

what i’d like is for it to stay hidden until a unit is selected, then it appears. and then it will hide again when the unit has made its move and is no longer selected

i dont know what code would be useful to include but i will include the script for the unit

i created a signal called active that i was going to use for the card to appear. i had code for the card but it’s been deleted

## The board manages its position inside the game grid.
## The unit itself holds stats and a visual representation that moves smoothly in the game world.
@tool
class_name Unit
extends Path2D

## Emitted when the unit reached the end of a path along which it was walking.
signal walk_finished

## Emitted when the unit is selected.
signal active

## Shared resource of type Grid, used to calculate map coordinates.
@export var grid: Resource
## Distance to which the unit can walk in cells.
@export var move_range := 6
## The unit's move speed when it's moving along a path.
@export var move_speed := 600.0
## Texture representing the unit.
@export var skin: Texture:
	set(value):
		skin = value
		if not _sprite:
			# This will resume execution after this node's _ready()
			await ready
		_sprite.texture = value
## Offset to apply to the `skin` sprite in pixels.
@export var skin_offset := Vector2.ZERO:
	set(value):
		skin_offset = value
		if not _sprite:
			await ready
		_sprite.position = value

## Coordinates of the current cell the cursor moved to.
var cell := Vector2.ZERO:
	set(value):
		# When changing the cell's value, we don't want to allow coordinates outside
		#	the grid, so we clamp them
		cell = grid.grid_clamp(value)
## Toggles the "selected" animation on the unit.
var is_selected := false:
	set(value):
		is_selected = value
		if is_selected:
			_anim_player.play("selected")
			emit_signal("active")
		else:
			_anim_player.play("idle")

var _is_walking := false:
	set(value):
		_is_walking = value
		set_process(_is_walking)

@onready var _sprite: Sprite2D = $PathFollow2D/Sprite
@onready var _anim_player: AnimationPlayer = $AnimationPlayer
@onready var _path_follow: PathFollow2D = $PathFollow2D


func _ready() -> void:
	set_process(false)
	_path_follow.rotates = false

	cell = grid.calculate_grid_coordinates(position)
	position = grid.calculate_map_position(cell)

	# We create the curve resource here because creating it in the editor prevents us from
	# moving the unit.
	if not Engine.is_editor_hint():
		curve = Curve2D.new()


func _process(delta: float) -> void:
	_path_follow.progress += move_speed * delta

	if _path_follow.progress_ratio >= 1.0:
		_is_walking = false
		# Setting this value to 0.0 causes a Zero Length Interval error
		_path_follow.progress = 0.00001
		position = grid.calculate_map_position(cell)
		curve.clear_points()
		emit_signal("walk_finished")


## Starts walking along the `path`.
## `path` is an array of grid coordinates that the function converts to map coordinates.
func walk_along(path: PackedVector2Array) -> void:
	if path.is_empty():
		return

	curve.add_point(Vector2.ZERO)
	for point in path:
		curve.add_point(grid.calculate_map_position(point) - position)
	cell = path[-1]
	_is_walking = true


func _on_button_pressed() -> void:
	pass # Replace with function body.

any information would be helpful as i am extremely new to gdscript

I haven’t read your code but usually when you want to instantiate something you store it as a packed scene by drawing the scene from the bottom left corner menu into the script holding ctrl.

A line will then pop up, looking like this
const EXAMPLE_NAME = preload(“res://example_name.tscn”)

Do this at the top of the script, somewhere below the extends and the _ready.

Now you have a reference to the scene you want to instantiate. Later on, when you want the card to appear, you can write:
var card_instance = EXAMPLE_NAME.instantiate()
card_instance.position = pick the position of the card
get_tree().add_child(“card_instance”)

Or is the problem that you are not sure how to connect the mouse click to the spawning in of the card? I think you could use a control node and the built in on_focus_entered signal to reveal the card, and focus exited signal to queue free.

This doesn’t just hide and reveal, but removes and respawns the card each time. I misunderstood your question a bit but I think that this is more beginner friendly as just hiding a card or menu will not prevent you from interacting with it. You need to set its mouse filter to false as well.

If you just want the card to appear/disappear, include it in the unit-scene and set it to invisible and MOUSE_FILTER_IGNORE = true. Ad a clickable control node to the unit as well. Connect both focus entered and exited to the same function. The function could read “card.visible = !card.visible
MOUSE_FILTER_IGNORE = !MOUSE_FILTER_IGNORE”
This sets the visibility and mouse filter to the opposite of what it is each time the control node enters or exits focus

thank you, all of these methods sound really useful and I will refer back to them

i don’t know how instantiate works so I will read up on that, but it sounds like it’s very close to what i need for this card menu

i will also try using the control nodes method . i think i had made this too complicated for myself at first

Sure! If something pops up just ask!