Trouble with visibility/show()/hide()

Godot Version

4.5.1 stable

Question

Hi there,

I’m new to programming and followed along this tutorial series for a basic 2D platformer:

Everything worked fine, and I even managed to change some things I didn’t like on my own (yay!)

So now that I’m kind of done with the tutorial, I wanted to add some more functionality.
There’s a flag in the game (area2d→animatedsprite2d/collisionshape2d). I want the flag to appear when the score hits 5. For the past 10hours I tried so many things and nothing worked.

I tried .hide()/.show() and the .visible true/false variants. In the main scene, and in the flag itself.
Right now I can get the flag to be visible or invisible on level load, but not, if the score hits 5. Nothing happens.

In my head it’s like this:

func _ready() → void:
if score.score <5:
visible = false
else:
visible = true

Since I tried so much stuff, I ended up storing the score on an autoload script and the score variable in it.
It works for the level ending (changing levels only works, when score reaches 5), but the visibility won’t change.

The flag is a scene on it’s own and has a script attached to it.

flag script at the moment:

extends Area2D


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	if score.score <5:
		visible = false
	else:
		visible = true
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
	pass

main script at the moment:

extends Node2D
@onready var score_label: Label = $HUD/ScorePanel/ScoreLabel
@onready var fade: ColorRect = $HUD/Fade
@onready var yeah_sound: AudioStreamPlayer2D = $YeahSound
@onready var flag = get_node("LevelRoot/Flag")


var level: int = 1
var current_level_root: Node = null

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	# Set up the level
	fade.modulate.a = 1.0
	current_level_root = get_node("LevelRoot")
	await _load_level(level, true, false)
	print(level)
	
# -----------------------
# LEVEL MANAGEMENT
# -----------------------

func _load_level(level_number: int, first_load: bool, reset_score: bool) -> void:
	# Fade out
	if not first_load:
		await _fade(1.0)
		
	if reset_score: 
		score.score = 0
		score_label.text = "Äpfel: 0"
		
	if current_level_root:
		current_level_root.queue_free()
		
	# Change level
	var level_path = "res://scenes/Levels/level%s.tscn" % level_number
	current_level_root = load(level_path).instantiate()
	add_child(current_level_root)
	current_level_root.name = "LevelRoot"
	_setup_level(current_level_root)
	await _fade(0.0)

func _setup_level(level_root) -> void:
	# Connect Exit
	var exit = level_root.get_node_or_null("Exit")
	if exit:
		exit.body_entered.connect(_on_exit_body_entered)
	
	# connect apples
	var apples = level_root.get_node_or_null("Apples")
	if apples:
		for apple in apples.get_children():
			apple.collected.connect(increase_score)
	
	# connect enemies
	var enemies = level_root.get_node_or_null("Enemies")
	if enemies:
		for enemy in enemies.get_children():
			enemy.player_died.connect(_on_player_died)
			

# -----------------------------
# SIGNAL HANDLERS
# -----------------------------

func _on_exit_body_entered(body: Node2D):
	if body.name == "Player" and score.score == 5:
		level += 1
		print(level)
		yeah_sound.play()
		body.can_move = false
		await _load_level(level, false, true)

func _on_player_died(body):
	body.die()
	await _load_level(level, false, true)
	print ("You died")
# -----------------------------
# SCORE
# -----------------------------

func increase_score() -> void:
	score.score += 1
	score_label.text = "Äpfel: %s" %score.score

# -----------------------------
# FADE
# -----------------------------

func _fade(to_alpha: float) -> void:
	var tween := create_tween()
	tween.tween_property(fade, "modulate:a", to_alpha, 1.5)
	await tween.finished

scene tree flag

scene tree main

All I want is that the flag is hid and appears when the score hits 5 so the player gets noticed to reach for the exit.

Sorry for the noob question. I really tried figuring it out on my own.
thanks in advance!

Your current code:

func _ready() -> void:
	if score.score <5:
		visible = false
	else:
		visible = true

checks the score exactly once (when the node enters the scene tree for the first time) and never again.
To make the flag visible as soon as the score hits 5, you need to check whenever the score increases:

# main script

# ...

func increase_score() -> void:
	score.score += 1
	score_label.text = "Äpfel: %s" %score.score

	if score.score < 5:
		flag.visible = false
	else:
		flag.visible = true

# ...
1 Like

Thanks for your help!

I managed to get it to work. I just put the if-statement for the score in the flag scene into the _process()-function instead of the _ready()-function.

That did the trick!