Can't get signals from instances

Godot Version

Godot 4.2.1 stable

Question

I have a coin scene and signal from it, which works fine. However, when I put copies of that scene on a level, signal are not working.
I have Coin scene and Player scene, where character touches coins and adds to sum of the coins.

you probably didn’t connect the copied coin to the function

Would you please tell how to do that?

sure. can you show me your node tree and code

nodeTree

in coin.gd:

signal coin_collected()


func _on_body_entered(body):
	coin_collected.emit()
	queue_free()

in level.gd:

func _ready():
	var new_coin: PackedScene = preload("res://coins/coin.tscn")
	var coin = new_coin.instantiate()
	add_child(coin)

in player.gd:

extends CharacterBody2D

var coins = 0

func _on_coin_coin_collected():
	coins += 1
	if coins > 0:
		print(coins)

can you create a node2D and put all the coin scene in it

Sure. Done.

what is the name of the node you just made

I named it Coins

great!
now add this code to your _ready func or if you don’t have one just copy and paste it

func _ready():
	for i in $"../Coins".get_child_count():
		$"../Coins".get_child(i).connect("coin_entered",coin_collected)

Where should I put this code, in what node?
And could you please explain this part

connect("coin_entered",coined)

you should put it in the place where you count the coin
I would recommend putting it in the level.gd where you instantiate your coin

[the node].connect([what signal should the code receive],[what func to execute])

It didn’t work

this is what you should put on your coin.gd

extends Area2D

signal coin_entered

func _on_body_entered(_body):
	emit_signal("coin_entered")
	queue_free()

Yes, but It works only in level.gd, but I need it to work in player.gd where is my game logic is.

If that the case

coin.gd

extends Area2D

signal coin_entered

func _on_body_entered(_body):
	emit_signal("coin_entered")
	queue_free()

level.gd

extends Node2D

@onready var coins = $Coins

# Called when the node enters the scene tree for the first time.
func _ready():
	var new_coin: PackedScene = preload("res://coins/coin.tscn")
	var coin = new_coin.instantiate()
	coin.connect("coin_entered",coin_collected)
	add_child(coin)

	for i in coins.get_child_count():
		coins.get_child(i).connect("coin_entered",coined)

func coined():
	emit_signal("coin_funel")

player.gd:

extends CharacterBody2D

@onready var level = $".."

var coins = 0

func _ready():
	level.connect("coin_funel",coin_collected)

func coin_collected():
	coins += 1
	if coins > 0:
		print(coins)

There is an error in level.gd:

Identifier "coin_collected" not declared in the current scope.

my mistake I wrote it without the debug
try this:

extends Node2D

@onready var coins = $Coins

# Called when the node enters the scene tree for the first time.
func _ready():
	var new_coin: PackedScene = preload("res://coins/coin.tscn")
	var coin = new_coin.instantiate()
	coin.connect("coin_entered",coined)
	add_child(coin)

	for i in coins.get_child_count():
		coins.get_child(i).connect("coin_entered",coined)

func coined():
	emit_signal("coin_funel")
1 Like

Thanks for your help. I manually add coins to the scene and now have another issue:
after game runs one instance of coins appears at top left corner with (0,0) coordinates like in Coin scene. How to avoid that?

your old code has this line so I assume you still want to spawn that coin
here is the updated code for
level.gd

extends Node2D

@onready var coins = $Coins

# Called when the node enters the scene tree for the first time.
func _ready():
	for i in coins.get_child_count():
		coins.get_child(i).connect("coin_entered",coined)

func coined():
	emit_signal("coin_funel")
1 Like