This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
0 votes

I'm fairly new to Godot and so for my first real project I'm working on a tower defense game. I've run into a bit of a snag though, I'm trying to use a signal to update the health of your "crystal" when an enemy reaches it but the signal can't seem to find the function I've connected it to in my ui.

In my crystal script I've got two functions:

onready var health_bar = get_node("/root/Main/CanvasLayer/GUI/HBoxContainer/Bars/LifeBar")

signal crystal_damaged

func _ready():
  connect("crystal_damaged", health_bar, "_on_crystal_damaged")

func hurt(value):
  hp -= value
  emit_signal("crystal_damaged", hp)

And in my LifeBar script I've got:

func _on_crystal_damaged(new_hp):
  --snip--

The connect call seems to work (returns 0) but then when I try to run emit_signal, I get Error calling method from signal 'crystal_damaged': 'HBoxContainer::_on_crystal_damaged': Method not found.

I've already checked that the get_node at the top works, the signal name is the same in all three places and the function name matches between scripts (I even copied it directly just to be sure) but still no luck.

Unfortunately I have to do this through scripting since I'm adding the crystal through scripting.

I'm at a total loss here, is this a bug or am I missing something really obvious?

in Engine by (12 points)

1 Answer

0 votes

Since you are wiring all of this up via script, I would use an autoloaded signal script. This is what I usually do:

# Signals.gd
extends Node

signal crystal_damaged
func crystal_damaged(hp):
    emit_signal("crystal_damaged", hp)

# Crystal.gd
func hurt(value):
    hp -= value
    Signals.crystal_damaged(hp)

# Lifebar.gd
extends HBoxContainer

func _ready():
    Signals.connect("crystal_damaged", self, "_on_crystal_damaged")

func _on_crystal_damaged(hp):
     # do whatever

You will need to set up Signals.gd as an autoloaded script, which won't be attached to a scene, it just lives on it's own and will be available everywhere. This approach lets you set up signals that can be emitted and listened to by nodes without knowing anything about each other or whether they exist or not.

by (1,663 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.