How to connect a signal from one scene to another scene?

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

Hi!

I am trying to instantiate a Bullet Node in another Scene. I want this because I want to separate the Bullet Scene from any other Scene and only instantiate it in a Scene when a certain Signal occurs. I tried to follow this example:

Unfortunately, it is not possible to use the Node tab to connect Signals because the Scene which emits the Signal does not see the other Scene where it should connect to.

I read that I can do it programmatically, something like this: bullet.connect(“shoot”, self, “_on_Player_shoot”)

But this does not work for me somehow.

This is my Bullet Script from one Scene:

extends Node2D

signal shoot(bullet, direction, location)

onready var bullet = load("res://Scenes/Bullet.tscn")

func _input(event):
    if event is InputEventMouseButton:
	    if event.button_index == BUTTON_RIGHT and event.pressed:
		    emit_signal("shoot", bullet, rotation, position)

func _process(delta):
    look_at(get_global_mouse_position())

I want to connect it to a Player Node in another Scene, I tried something like this
in the Player.gd script which doesn’t work

onready var bullet = preload("res://Scripts/Battle/Bullet.gd")

func _ready():
    bullet.connect("shoot", self, "_on_Player_shoot")

func _on_Player_shoot(bullet, direction, location):
    var b = bullet.instance()
    print("shoot!")
    add_child(b)
    b.rotation = direction
    b.position = position
    b.velocity = b.velocity.rotated(direction)

What do I need to do here to make this work? Is there a better way than doing it programmatically like this?

:bust_in_silhouette: Reply From: RazorSh4rk

Connect the signal after you instance the bullet

edit: also I think you want to instance bullet.tscn instead of .gd

I am not sure how this works? Would you mind providing an example?
I tried out different ways, I am not able to get it to work …

BennieBe | 2020-06-03 21:28

Hello there! I know this reply is super late, but I hope it might help anyone else who stumbles on the forum looking for help.

I had some trouble with this (and signals in general) as well. I believe you might want to structure your code differently. I would have the bullets be a child of a weapon or the player rather than a scene that tries to interact with inputs. For my first game I have the player instance a bullet through a function that is activated with input on the player script, and the bullet then has its own script that tells it how to move and damage, ect.

Otherwise you can relay signals so that they are at the same level as whoever you want to pick up your signal. For Example: In my first game I have these dinosaurs that emit a signal when they die. Since I instance my dinosaurs with a spawning function I can use that to connect my spawner node with their death signal:

extends Node2D

@onready var hunter = $".."
@onready var stego_scene = preload("res://Fauna/stego.tscn")
@onready var timer = $"../SpawnTimer"

signal dino_died()

func _ready():
	pass

func _process(delta):
	pass

#dino spawning
func _on_spawn_timer_timeout():
	print("dino spawning")
	timer.one_shot = true
	timer.start()
	var rand_distance = Vector2(randi() % 500 + 500, randi() % 500 + 500)
	var stego_instance = stego_scene.instantiate()
	
	stego_instance.died.connect(_on_dino_died)
	
	stego_instance.global_position = hunter.global_position+rand_distance
	add_child(stego_instance)
	
func _on_dino_died():
	dino_died.emit()

Here I am connecting the stego_instance’s died signal to emit another signal from the spawner which is already loaded in with the player. This way the player or “hunter” in my case can pick up on the signals emitted by the dinosaurs that don’t yet exist.

I am a total newb, so I wouldn’t read my code as the gospel, but I hope this might help offer some solutions to your problem!

1 Like