Error calling method from signal: Hit signal doesn't find Game Over and New Game method

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

Hi,

I just started, a few days ago, Your first 2D Game tutorial, but I’m having some issues with Hit() signal. I’m using C# and Visual Studio 2022.

I followed all instructions from the tutorial, but it seems Hit() signal can’t see the Game_Over() and New_Game() method in the Main.cs. It seems there is some bug or some mistake from my part(high probability).

Update about the Error Or Possible Bug: (I noticed only the next day!!!)
I noticed that after I deleted New_Game() and Game_Over() signals that was attached
to the Player.cs and keep only the ones attached to the Main.cs… After I save the application, close the application and open it again, the two signals that I deleted previously comes back. See the screenshots below:
Screenshot with duplicated signal methods

I’m posting here my scripts and my screenshots so that you help me, please, finding the missing piece!

Godot Screen with the Error:

GameOver signal:
GameOverSignal

NewGame signal:
NewGameSignal

Error details screenshot:
Error Detail

Main.sc script:

using Godot;
using System;

public class Main : Node
{
// Declare member variables here. Examples:
// private int a = 2;
// private string b = "text";

#pragma warning disable 649
[Export]
public PackedScene MobScene;
#pragma warning restore 649

public int Score;

// Called when the node enters the scene tree for the first time.
public override void _Ready()
{ 
    GD.Randomize();
    New_Game();
}

//  // Called every frame. 'delta' is the elapsed time since the previous frame.
//  public override void _Process(float delta)
//  {
//      
//  }

public void Game_Over()
{
    GetNode<Timer>("MobTimer").Stop();
    GetNode<Timer>("ScoreTimer").Stop();
}

public void New_Game()
{
    Score = 0;

    var player = GetNode<Player>("/root/Main/Player");
    var startPosition = GetNode<Position2D>("/root/Main/StartPosition");
    player.Start(startPosition.Position);

    //GetNode<Timer>("/root/Main/StartTimer").Start();
    Timer StartTimer = GetNode<Timer>("/root/Main/StartTimer");
    StartTimer.Start();
}

public void On_StartTimer_Timeout()
{
    GetNode<Timer>("MobTimer").Start();
    GetNode<Timer>("ScoreTimer").Start();
}

public void On_ScoreTimer_Timeout()
{
    Score++;
}

public void On_MobTimer_Timeout()
{
    //Create a new instance of the Mob Scene
    var mob = (Mob)MobScene.Instance();

    //Choose a random Location on Path2D
    var mobSpawnLocation = GetNode<PathFollow2D>("MobPath/MobSpawnLocation");
    mobSpawnLocation.Offset = GD.Randi();

    //Set the mon's direction perpendicular to the path direction.
    float direction = mobSpawnLocation.Rotation + Mathf.Pi / 2;

    //Set the mob's position to a random location.
    mob.Position = mobSpawnLocation.Position;

    //Add some randomness to the direction
    direction += (float)GD.RandRange(-Mathf.Pi / 4, Mathf.Pi / 4);
    mob.Rotation = direction;

    // Choose the velocity.
    var velocity = new Vector2((float)GD.RandRange(150.0, 250.0), 0);
    mob.LinearVelocity = velocity.Rotated(direction);

    // Spawn the mob by adding it to the Main scene.
    AddChild(mob);

}
}

Player.sc script:

using Godot;
using System;

public class Player : Area2D
{
// Declare member variables here. Examples:
// private int a = 2;
// private string b = "text";

//How fast the player will move (pixel/sec).
[Export]
public int Speed = 400;
[Signal]
public delegate void Hit();
// Size of the game window.
public Vector2 ScreenSize;

public int Score;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
    ScreenSize = GetViewportRect().Size;
    Hide(); //Player is hidden when the game starts
}

// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(float delta)
{
    var velocity = Vector2.Zero; //Tha Player's movement vector

    if (Input.IsActionPressed("move_right"))
    {
        velocity.x += 1;
    }
    if (Input.IsActionPressed("move_left"))
    {
        velocity.x -= 1;
    }
    if (Input.IsActionPressed("move_down"))
    {
        velocity.y += 1;
    }
    if (Input.IsActionPressed("move_up"))
    {
        velocity.y -= 1;
    }

    var animatedSprite = GetNode<AnimatedSprite>("AnimatedSprite");

    if (velocity.Length() > 0)
    {
        velocity = velocity.Normalized() * Speed;
        animatedSprite.Play();

    }
    else
    {
        animatedSprite.Stop();
    }

    Position += velocity * delta;
    Position = new Vector2(
        x: Mathf.Clamp(Position.x, 0, ScreenSize.x),
        y: Mathf.Clamp(Position.y, 0, ScreenSize.y)
        );

    if (velocity.x != 0)
    {
        animatedSprite.Animation = "walk";
        animatedSprite.FlipV = false;
        animatedSprite.FlipH = velocity.x < 0; //Here I'm doing a boolean test
    }
    else if (velocity.y != 0)
    {
        animatedSprite.Animation = "up";
        animatedSprite.FlipV = velocity.y > 0; //Here I'm doing a boolean test
    }
}

public void On_Player_Body_Entered(PhysicsBody2D body)
{
    Hide(); //Player disappears after being hit.
    EmitSignal(nameof(Hit));//On_Player_Hit()
    //Must be deferred as we can't change physics properties on a physics callback.
    GetNode<CollisionShape2D>("CollisionShape2D").SetDeferred("disabled", true);
} 

//Reset the player when starting the game  
public void Start(Vector2 pos)
{
    Position = pos;
    Show();
    GetNode<CollisionShape2D>("CollisionShape2D").Disabled = false;
}
}

Mob.sc script:

using Godot;
using System;

public class Mob : RigidBody2D
{
// Declare member variables here. Examples:
// private int a = 2;
// private string b = "text";

// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
    var animSprite = GetNode<AnimatedSprite>("AnimatedSprite");
    animSprite.Playing = true;
    string[] mobTypes = animSprite.Frames.GetAnimationNames();
    animSprite.Animation = mobTypes[GD.Randi() % mobTypes.Length];
}

// // Called every frame. 'delta' is the elapsed time since the previous frame.
// public override void _Process(float delta)
// {
//     
//  }

public void OnVisibilityNotifier2DScreenExited()
{
    QueueFree();
}  
}

These are all my scripts!!!

Well, I think with all these information you can help me! If you need anything more, let me know, please!