How to Connect a Signal to an Instance of a Scene

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

I have a scene with an Area2D at the root, and have created a signal for when the mouse enters the sprite. When I run the scene on its own, when I mouse over the Area2D, I’m able to generate a message in the log just fine:

extends Area2D

signal mouse_touch

func _on_Letter_mouse_touch():
	print("Mouse touch")


func _on_Letter_mouse_entered():
	emit_signal("mouse_touch")

BUT-- from my ‘main’ scene, I’m trying to connect the same signal to an instance of a scene, but the mouseover does work from the main scene, something like this:

var c = Letter.instance()
c.connect("mouse_touch", self, "_on_Letter_mouse_touch")

Is this not the proper way to handle this?

Thanks!
Bryan

I’m a bit confused as to what you’re trying to do. Are you trying to connect the signal to the node that emits it? I’m not sure why you would do that. But your code right now connects it to the main scene (self).

exuin | 2020-10-02 04:51

No, the code where I’m connecting the signal to the node that emits it is just a test so that I can run just the scene by itself to test the mouse event(s).

What I’m trying to do is instantiate my scene from my main scene, and connect the “mouse_touch” signal to it, so that whenever the ‘Letter’ scene gets instanced and drawn to the screen, it reacts to being clicked on with the mouse…

Bryan

bcgreen24 | 2020-10-02 04:55

You have _on_Letter_mouse_touch as a function in the main scene’s script, right? Also, I’m not sure why you’re making your own signal instead of just connecting the Area2D’s pre-existing mouse_entered() signal.

exuin | 2020-10-02 05:06

Good question :slight_smile: …so I’m now using the ‘mouse_entered()’ signal, but same result-- when I connect it to my instanced object, nothing happens when I mouse over the instances.

When I add this to my ‘Letter’ scene:

func _on_Letter_mouse_entered():
print("Hello")

…the message gets printed when I run just the ‘Letter’ scene, but nothing happens when I run the ‘main’ scene.

Bryan

bcgreen24 | 2020-10-02 14:56

Well, did you also add the function to your main scene?

exuin | 2020-10-02 15:16

Yes, there is also a function to handle the mouse over in my main script.

bcgreen24 | 2020-10-02 15:34

Would it be possible to post more stuff, like your code and node layout?

exuin | 2020-10-02 15:49

main.gd:

extends Node2D

export (PackedScene) var Letter

export (int) var Playtime

var level
var score
var time_left
var screensize
var playing = false
var letter_array = []
var letter_cell
var letters = []
var word_list = ['bird', 'dog', 'cat', 'apple', 'food', 'house', 'mommy', 'daddy', 'milk']

func _ready():
    randomize()
    screensize = get_viewport().get_visible_rect().size

func _process(delta):
    if playing and $LetterContainer.get_child_count() == 0:
        level += 1
        time_left += 5
        $NewLevelSound.play()
        spawn_letters(word_list[randi() % 9])

func new_game():
    playing = true
    level = 1
    score = 0
    time_left = Playtime
    $HUD.update_score(score)
    $HUD.update_timer(time_left)
    $GameTimer.start()
    spawn_letters(word_list[randi() % 8])
    

func spawn_letters(word):
    letter_array.clear()
    for letter in word:
        letter_cell = Vector2(randi() % 9, randi() % 10)
        var result = letter_array.find(letter_cell)
        if result != -1:
            letter_array.remove(result)
        letter_array.append(letter_cell)
    var i = 0
    for letter in letter_array:
        var l: Area2D = Letter.instance()
        l.get_child(0).text = word.substr(i, 1)
        i = i + 1
        l.position = Vector2((letter[0] * 48) + 16, (letter[1] * 48) + 64)
        l.connect("_on_Letter_mouse_entered", self, "_on_Letter_mouse_touch")
        $LetterContainer.add_child(l)

func _on_GameTimer_timeout():
    time_left -= 1
    $HUD.update_timer(time_left)
    if time_left <= 0:
        game_over()


func _on_Player_pickup(type):
    match type:
        "letter":
            $CoinSound.play()
            score += 1
            $HUD.update_score(score)

func game_over():
    $GameOverSound.play()
    playing = false
    $GameTimer.stop()
    for letter in $LetterContainer.get_children():
        letter.queue_free()
    $HUD.show_game_over()
    #$Player.die()

func _on_HUD_start_game():
    new_game()

func _on_Letter_mouse_touch():
    print("Mousey")

Letter.gd:

extends Area2D

func _on_Letter_mouse_entered():
print("Hello")

func _on_Letter_mouse_touch():
print("Mousey")

Letter scene signal:

Imgur: The magic of the Internet

bcgreen24 | 2020-10-02 16:40

l.connect("_on_Letter_mouse_entered", self, "_on_Letter_mouse_touch")

So _on_Letter_mouse_entered is not the signal, but is instead the name of the function. You want to connect the mouse_entered signal.

exuin | 2020-10-02 17:22

Ah, my mistake…however, changing that to “mouse_entered” still has no effect.

Bryan

bcgreen24 | 2020-10-02 18:54

I recreated your scene minimally and I wasn’t able to get your error. I’m sorry, I think there might be something else wrong.

exuin | 2020-10-03 01:42