I am having an issue were my custom signal is not working, in my game the player can pick up a heart that will then heal the player, when this happens the player will have a small heal effect the goes over them. I know the function for the effect to pop up works fine, I had the player regenerate health overtime and it worked.

The heart has a signal called "Heal" when the player is able to pick it up it will heal the player, then fire the signal and delete itself , the issue is that the player will not receive the signal even though I have it connected correctly (I am confident that it is connected properly but I could be wrong )

Here are the fallowing pieces of my code, I really hope this helps, I also added in the function for the in case there seems to be a problem with that as well

Heart script

Defining the heart autoload

the Connection

effect function

I looked it up online and several people had the same problem but I have gotten no clear answers from their post, thank you in advance

This discussion was caught in the moderation queue since you have not confirmed your account yet.

Upon creating your account you should have received an account verification email. The confirmation email may have been incorrectly flagged as spam, so please also check your spam filter. Without confirming your account, future posts may also be caught in the moderation queue. You can resend a confirmation email when you log into your account if you cannot find the first verification email.

(Note: You do not need to repost, the discussion has been moved out and is visible now)

If you need any help, please let us know! You can find ways to contact forum staff on the Contact page. Thanks! :smile:

Welcome to the forums @HelpMePlease!

Does the heart autoload have the signal? It looks like the code that makes the connection is connecting to the heart autoload, rather than the heart itself, which may be why it's not working.

What you may want to do is have the heart autoload have the signal, and then when the player collides with a heart, have the heart node call a function on the heart autoload that emits the signal to the player. That way, you can have the player just connect to the heart autoload once. With having the signal on the heart itself, you would need to have the player connect a signal to each heart node, which may not be ideal if you have many hearts in the scene.

For the code, I think something like this would work (untested):

# =============
# Heart Script
extends Area2D
onready var stats = PlayterStates
func _on_Heart_body_entered(body):
	if body.is_in_group("player"):
		if stats.health < stats.max_health:
			Heart_Autoload.on_health_pickup()
			stats.health += 1
			queue_free()
# =============

# ===============
# The heart autoload
signal Heal
func on_health_pickup():
	emit_signal("Heal")
# ===============

# ===============
# The connection
Heart_Autoload.connect("Heal", self, "healing_effect")
# ===============

I'm not totally sure it would work, but I think it will. I would make a backup of your project first though, just in case it doesn't work so you don't lose anything.

connect() returns error code. Check it so see if connection is established. If it returns a nonzero value, the connection failed.

Secondly, put a simple print statement in the signal callback to see if it even gets called.

thank you @TwistedTwigleg and @xyz, The heart node is an auto load, so the function when the player collects the heart is in and should work, I also did have a print statement in both of the functions so see which one worked, that is how I was able to find out that the connection wasn't working

Did you check the return value when calling connect() ?

Any script that uses a signal needs the signal defined at the top of the script. So:

signal Heal

Needs to be on any script that interfaces with the signal (whether emit or connect).

@cybereality said: Any script that uses a signal needs the signal defined at the top of the script. So:

signal Heal

Needs to be on any script that interfaces with the signal (whether emit or connect).

Are you sure about that? Documentation isn't explicit but judging from examples it just needs to be declared in classes that emit. I do this in my code and it appears to be working fine. Note that connect() is here called from the target but it's called as a method of an object that emits.

I could have swore I tested this a while ago and that was needed, but maybe I was mistaken. I just tested it again and it seems you are correct. The signal only needs to be declared in the script that emits it. Sorry.

@cybereality said: I could have swore I tested this a while ago and that was needed, but maybe I was mistaken. I just tested it again and it seems you are correct. The signal only needs to be declared in the script that emits it. Sorry.

I see custom signals just as a basic callback mechanism. Declaring a signal tells engine that class will accept callback registrations grouped under a certain name. Other objects can then register callbacks by calling connect(), and all callbacks registered under the same name get triggered when emit() is called.

comments:

consider using collision bits (add a bit for player for 'pickups' and add the pickups bit to the collision mask of the area)

instead of signaling the player, create a method to do all the healing logic there because the 'player' knows how healthy she/he/it is, and can return a value indicated consumption or not.

then your on-area-entered is:

func on_body_entered(player):
    if player.consume(potency):
        # (emit signals for) animations/sfx
         queue_free()
   else:
        # optional sounds/animations/signals on non use

and player code is

func consume(potency:int) -> bool:
   if full health: return false
  health += potency
  if health > max_health: heath = max_health
  # play animations, emit signals etc
  return true
a year later