Basic Area2D Collision Confusion

Godot Version

4.4.1.stable.mono.official.49a5bc7b6

Question

Beginner to Godot and gamedev in general, knowledgable about C# can't figure out why these two Area2D nodes are not registering a collision!

  1. Tried Setting Monitoring to true
  2. Ensured Collision Layer and Mask for both 2D Areas set to layer 1
  3. Tried With Both a 2D Area and a Character Body
using Godot;
using System;

public partial class Vipe : Area2D
{
    [Signal]
    public delegate void HitEventHandler();

    // Called when the node enters the scene tree for the first time.
    [Export] public float JumpVelocity = 3f;
    private Vector2 Velocity = Vector2.Zero;
    public const string UP = "fly_up";
    public Vector2 ScreenSize;

    public override void _Ready()
    {
        ScreenSize = GetViewportRect().Size;
        this.Monitoring = true;
    }

    // Called every frame. 'delta' is the elapsed time since the previous frame.
    public override void _Process(double delta)
    {
        if (Input.IsActionJustPressed(UP))
        {
            //Player hit jump
            Velocity = Vector2.Up * JumpVelocity;
            GD.Print("Flying!");
        }
        else
        {
            Velocity -= Vector2.Down * -Gravity * (float)delta;
        }

        Position += Velocity * (float)delta;
        Position = new Vector2(
            x: Mathf.Clamp(Position.X, 0, ScreenSize.X),
            y: Mathf.Clamp(Position.Y, 0, ScreenSize.Y)
        );
    }

    private void OnBodyEntered(Node2D body)
    {
        GD.Print("OnBodyEntered");
    }

    public void OnAreaEntered(Area2D area)
    {
        GD.Print("OnAreaEntered");
        if (area.Name == "Tower")
        {
            GD.Print("Tower Area Hit!");
        }

        if (area is Tower tower)
        {
            GD.Print("Tower Hit!");
        }
    }
}

Image of nodes in main scene, I have applied a simple gravity vector so Viper (green lizard) falls on the tower (white structure)

Did you happen to change the layer and mask on one of the Area2D’s? Could you provide a screenshot of those settings of both?

Edit: I must’ve missed that second bullet point, my bad. Back to analysing!

Edit2: Did you connect the signals via the editor? I believe (but my experience is based on Gdscript) just naming the signal the same doesn’t always connect it.

Hi! I’m about as knowledgeable as you are, but I did notice that your OnAreaEntered/OnBodyEntered aren’t hooked up in any way - at least not in the C# code. I don’t know how the C# integration works in Godot, but maybe you need to attach them to an event handler, or add an override keyword? I suspect it’s the latter, seeing how you’re using that for _Ready() and _Process.

I’m new to Godot but i tried a c# project where i made a simple catch game. I had an Area2D for the “basket”. to detact the falling objects (rigidbody2d) i had to add the Body Entered signal/event thing in the ready method

public override void _Ready()

    {

        // Area2D uses 'BodyEntered' for PhysicsBodies like RigidBody2D

        BodyEntered += OnBodyEntered;

    }

this worked for rigid bodies entering an area, you should be able to link up the AreaEntered in the same way I think

AreaEntered += YourMethodName;

2 Likes

I believe this is the programatic way of connecting signals opposed to the option via the editor right? I never used Godot with C#, but can you connect signals via the editor when using C# also?

Yes the programatic way, in c# when I try to connect a signal in the editor it gives this warning

and nothing is generated in the c# script

IIRC, you have to connect code programmatically yourself in C#. You can find tutorials online about how to do that.

As someone who has been a professional C# developer (and Java, C++, Ruby, Python..etc) I really recommend you try out GDScript even if you’re experienced with C#. You will find it a much easier experience. I made one game in C# with Godot after a year using GDScript. Never again.

1 Like

This is correct and even mentioned in the guide I was following,.

I see this snipped from the guide

// We also specified this function name in PascalCase in the editor's connection window.
private void OnBodyEntered(Node2D body)
{
    Hide(); // Player disappears after being hit.
    EmitSignal(SignalName.Hit);
    // Must be deferred as we can't change physics properties on a physics callback.
    GetNode<CollisionShape2D>("CollisionShape2D").SetDeferred(CollisionShape2D.PropertyName.Disabled, true);
}

And it makes me think that this method should behave as a callback, I tried a comment above and put the override keyword but I just got a red squiggly. I also couldnt find any of these “signal” methods attatched to the object I am extending Area2D

This is it, thanks for the help I couldn’t find how to use the already available signals only create new ones. This makes more sense
For anyone else who runs into this, the built in signals are C# events that you can bind callback functions using the method metalhippy did my code ended up like this.

public override void _Ready()
    {
        ScreenSize = GetViewportRect().Size;
        this.Monitoring = true;
        // AreaEntered is the event we are observing
        //ShitHappens is the callback function
        AreaEntered += ShitHappens;
    }

    private void ShitHappens(Area2D area)
    {
        GD.Print("Shit Happened");
    }
1 Like

Glad you got it working, good luck with the game

If you have defined a method with proper signature then you can pick it in this dialog and the signal gets connected just fine. It simply does not generate the method for you.