4

I have a Signal inside a script attached to a node:

Game.tscn/Game.cs

using Godot;

public class Game : Node2D
{
    [Signal]
    public delegate void AddPowerUp(Powerup powerup);
}

I try to emit a signal from another class:

ExtraBall.tscn/Powerup.cs

public override void _IntegrateForces(Physics2DDirectBodyState state)
{
    EmitSignal("AddPowerUp", this);
}

Then in another scene, Level.tscn, I instanced Game and ExtraBall. However, I get an error when I try to emit the signal.

E 0:00:05.828   emit_signal: Can't emit non-existing signal "AddPowerUp".

Here's how it looks like in the engine:

Game has the Signal and I attach to a function in Player:

In the Level scene, I instance Game and ExtraBall:

Shouldn't ExtraBall be able to know about the "AddPowerUp" signal since it was instanced under the same SceneTree? If not, how do I go about emitting a signal that's defined somewhere else?

cress
  • 389
  • 3
  • 13

1 Answers1

0

I ended up doing it a different way.

  • I removed the Game instance from the Level scene.
  • Declared the signal inside ExtraBall.cs
  • Created an instance of Level inside Game
  • Connected the signal from ExtraBall to a function inside Player through code.

The scene trees are as follows:

Game (Node2D)
  Player (Player.tscn)

Level (Node2D)
  ExtraBall (Extraball.tscn)

Not sure if this is a good approach, but it seems to work without any issues. I posted a small "game" that shows the solution at the bottom.

Game.cs

public class Game : Node2D
{
    [Signal] public delegate void LevelLoaded();

    public override void _Ready()
    {
        PackedScene scene = ResourceLoader.Load("res://source/level/Level.tscn") as PackedScene;
        AddChild(scene.Instance());
        EmitSignal("LevelLoaded");
    }
}

Player.cs

public class Player : KinematicBody2D
{
    public override void _Ready()
    {
        GetNode<Node>("/root/Game").Connect("LevelLoaded", this, "OnLevelLoaded");
    }

    public void OnLevelLoaded()
    {
        GetNode<Node>("/root/Game/Level/ExtraBall").Connect("TestSignal", this, "OnTestSignal");
    }

    public void OnTestSignal()
    {
        GD.Print("YAY!");
    }
}

ExtraBall.cs

public class ExtraBall : RigidBody2D
{
    [Signal] public delegate void TestSignal();

    public override void _IntegrateForces(Physics2DDirectBodyState state)
    {
        var bodies = GetCollidingBodies();

        foreach (Node2D node in bodies)
        {
            EmitSignal("TestSignal");
        }
    }
}

Small project with solution: https://www.dropbox.com/s/v7zac3lripsslrz/SignalTest.zip?dl=0

cress
  • 389
  • 3
  • 13