Context

The project is written using C#. I'm using v3.2.3-stable_mono. I'm running windows 10 (x64)

I'm trying to create an AutoLoad/Singleton that handles logic related to which layer the player is on. The Singleton has: - A function to initiate a layer switch. - A function to poll the current layer. - A signal that is triggered every time the layer is switched.

I've written a class that reacts to layer switches. This will be a collision Polygon that will only be active on the specified layer. However currently only code to test the signal has been implemented. The signal is connected through code, as I do not want to reconnect the signal for every collision polygon. The class simply connects to the delegate on the singleton on _Ready().

Problem

When running the game the following error is thrown:

E 0:00:02.566   emit_signal: Error calling method from signal 'OnSwitchLayer': 'CollisionPolygon2D(DynamicLayerCollisionPolygon.cs)::OnSwitchLayer': Method not found..
  <C++ Source>  core/object.cpp:1260 @ emit_signal()
  <Stack Trace> :0 @ void Godot.NativeCalls.godot_icall_2_591(IntPtr , IntPtr , System.String , System.Object[] )()
                Object.cs:359 @ void Godot.Object.EmitSignal(System.String , System.Object[] )()
                DynamicLayerSingleton.cs:14 @ void DynamicLayerSingleton.SwitchLayer(Byte )()
                DynamicLayerCollisionPolygon.cs:18 @ void DynamicLayerCollisionPolygon._Ready()()

Solutions I tried

I've considered that C# support could just not be there, but both documentation pages for Singleton and signal have C# versions, implying that C# is supported.

I've tried changing the name of the function and the third parameter of the Connect() function. I've tried the following: - _OnSwitchLayer - On_Switch_Layer - _On_Switch_Layer - _on_switch_layer - _on_Switch_Layer

However, all of these failed and the documentation states that the snake case versions only apply to build in functions:

There are some methods such as Get()/Set(), Call()/CallDeferred() and signal connection method Connect() that rely on Godot's snake_case API naming conventions. So when using e.g. CallDeferred("AddChild"), AddChild will not work because the API is expecting the original snake_case version add_child. However, you can use any custom properties or methods without this limitation. Link.

Am I missing something or is this some specific issue? I've looked over the documentation multiple times, and I cannot find any differences, except that I'm both creating and connecting the signal in C#.

Code

DynamicLayerSingleton.cs this is the singleton

using Godot;
using System;

public class DynamicLayerSingleton : Node
{
	private byte currentLayer = 0;

	[Signal]
	public delegate void OnSwitchLayer(byte newLayer);

	public void SwitchLayer(byte newLayer)
	{
		this.currentLayer = newLayer;
		EmitSignal(nameof(OnSwitchLayer));
	}

	public byte GetCurrentLayer()
	{
		return this.currentLayer;
	}
}

DynamicLayerCollisionPolygon.cs

using Godot;
using System;

public class DynamicLayerCollisionPolygon : CollisionPolygon2D
{

    public void OnSwitchLayer(byte newLayer)
    {
        GD.Print(newLayer);
    }
    public override void _Ready()
    {
        DynamicLayerSingleton dynamicLayer = (DynamicLayerSingleton)GetNode("/root/DynamicLayerSingleton");
        dynamicLayer.Connect(nameof(DynamicLayerSingleton.OnSwitchLayer), this, nameof(OnSwitchLayer));

        GD.Print(this.HasMethod(nameof(OnSwitchLayer)));

        dynamicLayer.SwitchLayer(5);
    }
}
a month later

You are emitting your signal...

EmitSignal(nameof(OnSwitchLayer));

...with no arguments, but you are specifying a delegate method that accepts a 'byte' argument. The signatures won't match.

Either emit your signal with an argument (EmitSignalaccepts varargs) or use a delegate method that takes no arguments.

2 years later