Trouble calling a function from another file

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

Inside Main.gd:
func game_over(): $ScoreTimer.stop() $MobTimer.stop() $HUD.show_game_over() $HUD.show_message("Game Over") get_tree().call_group('mobs', 'queue_free') $Music.stop() $Deathsound.play()

Inside Player.gd:
func _on_Stats_no_health(): hide() $CollisionShape2D.set_deferred("disabled", true) var scene = preload("res://Main.gd") var over = scene.instance() over.game_over()

Inside Stats.gd:
func set_health(value): health = value emit_signal("health_changed", health) if health <= 0: emit_signal("no_health")

When it is supposed to be game over I want what is inside Main.gd to run. I am trying to use Stats.gd to emit “no_health” and have _on_Stats_no_health() pick it up and call gameover(). I am very new to godot. Any help is appreciated.

:bust_in_silhouette: Reply From: timothybrentwood

is your player a child of the Main node?
assuming Stats is a child of Player which is a child of Main, your Player.gd should look something like this:

var player_stats
func _ready():
    # get the node directly
    player_stats = $Stats
    # then connect the "no_health" signal to the Player, calling  _on_Stats_no_health()
    player_stats.connect("no_health", self, "_on_Stats_no_health")

func _on_Stats_no_health(): 
    hide() 
    $CollisionShape2D.set_deferred("disabled", true) 
    get_parent().game_over()

The above assumes your node structure looks like this:

|-> Main
|—> Player
-----|—> Stats

Hmm, Unfortunately, No that doesn’t work.

Would you take a look at my code?
https://github.com/francescainfranca/godot-game-over

I tried to print out some feedback to find if the function executes, because the hide() inside _on_Stats_no_health() seems to run since the player disappears after 3 hits. But any print statement I put in the same function does not print. I am so confused.

toshnewton | 2021-04-28 00:15

In Player.gd change your ready function from:

func _ready():
	stats.connect("no_health", self, "queue_free")
	screen_size = get_viewport_rect().size
	hide()

to

func _ready():
	stats.connect("no_health", self, "_on_Stats_no_health")
	screen_size = get_viewport_rect().size
	hide()

This connects the "no_health" signal emitted from stats to the "_on_stats_no_health()" function rather than the "queue_free()" function. So essentially what’s happening is when stats emits the signal "no_health" the Player object picks it up and calls self._on_Stats_no_health() which goes on to call get_parent().game_over(). When Player.gd calls get_parent(), it receives your Main Node in your scene tree (top left), because Player is a child of Main. Hope that helps explain what’s going on under the hood.

timothybrentwood | 2021-04-28 01:15

Works Perfect! Thanks!

toshnewton | 2021-04-28 01:24