Unable to get signal from C# script onto main Gd application scripts (Godot 4.2).

Godot Version

v4.2.1.stable.mono.official [b09f793f5]

Question

I’m struggling to get a signal from a C# script to a .gd script. I’ve found other questions similar to this one but I’m unable to pinpoint what’s the issue with my code.

My main scene is a Node3D object called Match.tscn which has a script Match.gd attached to it. My Match scene has a child Object “ConnectionManager” (Type: Node).

The ConnectionManager node has a script attached (ConnectionManager.gd) which instantiates a C# script. Unfortunately the code I have is on C# only.

I also have a script called MatchSignals.gd that handles the signals for my main game. Signals between Match.gd and other gd scrips seems to work just fine.

Below my (relevant) code:

Match.gd:

extends Node3D
@export var settings: Resource = null

@onready var _connection_manager = $ConnectionManager

func _ready():
	assert(_connection_manager != null, "match cannot start without connection manager")
	MatchSignals.my_broker_connected.connect(continue_match_setup)
	_connection_manager._connect_signals()
	_connection_manager._connect()

func continue_match_setup():
# --- Continue initialization here ---

ConnectionManager.gd:

extends Node
//this is my C# script
var cSharpInstance = preload("res://source/MyCSharpClass.cs")
var csi = cSharpInstance.new()

func _ready():
	add_child(csi)

func _connect_signals():
	if csi != null:
		if csi.has_signal("ConnectedSignal"):
			spbm.ConnectedSignal.connect(_on_connect)
		if spbm.has_signal("DisconnectedSignal"):
			spbm.DisconnectedSignal.connect(_on_disconnect)
		if spbm.has_signal("FailSignal"):
			spbm.FailSignal.connect(_on_fail)

func _connect_to_broker():
	csi.call("ConnectToBroker")

func _on_broker_connected():
	MatchSignals.my_broker_connected.emit();

MyCSharpClass.cs:

using Godot;
using System;

public partial class MyCSharpClass : Node
{
    [Signal] public delegate void ConnectedEventHandler();

    public async void ConnectToBroker()
    {
            // establish connection and stuff...
            if(connected){
                  EmitSignal("ConnectedSignal");
            }
     };
}

I expect that when the connection is established the signal “ConnectedSignal” is emmited, this in turn will activate the my_broker_connected signal and allow me to continue the initialization process. However I don’t see anything happening. I know the connection was established cause other fucntionality in my C# script that doesn’t require the signal is working after the connection, but the signal is not emitted (or somehow is not getting caught) by my ConnectionManager.gd script.

Is there any way to debug this further to understand what’s going on?

Based on other threads I’ve found I can confirm:

  1. The signals exist and are connected in my C# script, confirmed with:
csi.get_signal_connection_list("ConnectedSignal")
  1. As mentioned before, signals between my MatchSignals.gd and other signals work just fine, it’s just the C# signal that is giving me a headache.

Your C# script defines a signal like this:

[Signal] public delegate void ConnectedEventHandler();

The way signals work in C#, this is the delegate type used by the generated event which will be generated automatically behind the scenes, and it will look something like this:

public event ConnectedEventHandler Connected { add; remove; }

This means your signal is actually called “Connected”, not “ConnectedSignal”. The name of the signal is everything before the “EventHandler” suffix.

If your script has a signal named “ConnectedSignal” then it’s defined somewhere else, perhaps your are calling AddUserSignal somewhere.

1 Like