emit_signal() isn't emitting a signal

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

I am trying to work with custom signals. My code looks somewhat like this (abbreviated):
Bullet.gd

extends KinematicBody2D
signal hit_walln

func _process(delta):
  var collision = move_and_collide(velocity * delta)
  if collision.collider.name == 'WallN':
    print("Now emitting hit_walln")
    emit_signal("hit_walln")

Main.gd

func _on_hit_walln():
  print("recieved hit_walln")

I have tried connecting the signal both using the UI and using

func _ready():
  connect("hit_walln", get_node("Main"), "_on_hit_walln"

in Bullet.gd. Both Methods show the message “Now emitting hit_walln”, but only the method using the code shows the message “recieved hit_walln”. I am a bit stumped by this, because I have connected other (non custom) signals using the UI in the same project before (timeout() on Timers to be exact) and those work flawlessly.

Is there a difference between those I don’t see?

I get an error saying: “Non-static function emit_signal() can only be called from an instance.” My script is attached to a kinematicbody2d. I want to call emit in _process().

Stormwindy | 2019-06-18 14:21

:bust_in_silhouette: Reply From: paulhocker

In this scenario, I think it would be better if you use a Singleton to hold the signal, otherwise you have to connect Main to every single bullet that is instanced. I added the bullet object as a parameter in case you wanted to know which bullet hit the wall (probably not).

For example:

Singleton.gd

signal bullet_hit_walln(bullet)

Bullet.gd

func _process(delta):
  var collision = move_and_collide(velocity * delta)
  if collision.collider.name == 'WallN':
    print("Now emitting hit_walln")
    Singleton.emit_signal("bullet_hit_walln", self)

Main.gd

func _on_bullet_hit_walln(bullet):
  print(bullet, "bullet_hit_walln")

func _ready():
  Singleton.connect("bullet_hit_walln", get_node("Main"), "_on_bullet_hit_walln"

Why does it matter who (Singleton vs Bullet) owns the signal?

sygi | 2021-04-03 12:43

:bust_in_silhouette: Reply From: shield

The only difference is that I bet you connected the signal timeout on timers via editor, not by code. Bullet.gd does not have a predefined signal like the timer node does, so you have to create and connect your own signal via code.

Over here, you are able to see both methods.