+2 votes

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 hitwalln", but only the method using the code shows the message "recieved hitwalln". 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?

in Engine by (45 points)

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().

2 Answers

+2 votes
Best answer

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"
by (84 points)
selected by

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

0 votes

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.

by (202 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 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 webmaster@godotengine.org with your username.