I'm developing a 2D game where the player character can attack enemies using a designated attack area (Area2D node named AttackArea). I've encountered a problem where the AttackArea is active and monitoring for collisions from the start of the game, even before any attack actions are performed by the player. This causes enemies to register hits without any input from the player.

Expected Behavior:
I expect the AttackArea to activate and begin monitoring for collisions only when the player presses the attack button, triggering the attack animation.

Actual Behavior:
The AttackArea seems to be monitoring for collisions right from the beginning, resulting in enemies getting hit without the attack button being pressed.

Relevant Code Snippets:
Here's how I've set up the AttackArea and the player's attack logic:

extends Area2D

var can_attack = true
var attack_cooldown = 0.5
var is_attacking = false

func _ready():
    $AttackArea.set_monitoring(false)

func _process(delta):
    handle_movement_input(delta)
    handle_attack_input()

func _on_AnimatedSprite_animation_finished():
    if $AnimatedSprite.animation == "attack":
        $AttackArea.set_monitoring(false)
        is_attacking = false
        can_attack = true

func handle_attack_input():
    if Input.is_action_just_pressed("attack") and can_attack:
        $AnimatedSprite.play("attack")
        $AttackArea.set_monitoring(true)
        is_attacking = true
        can_attack = false
        yield(get_tree().create_timer(attack_cooldown), "timeout")
        $AttackArea.set_monitoring(false)
extends Area2D

var health = 100

func _on_EnemySoldier_area_entered(area):
    if area.is_in_group("player_attacks"):
        take_damage(30)

func take_damage(amount):
    print("Enemy hit!")
    health -= amount
    if health <= 0:
        die()

func die():
    queue_free()

Steps I've Taken:

I've verified the collision layers and masks are correctly set up for both the AttackArea and the enemy.
I've ensured the AttackArea is set to not monitor in the _ready function and only set to monitor within the handle_attack_input function.
I've added print statements to confirm the monitoring state of the AttackArea, which shows it being disabled after the attack is complete, but it's still active beforehand.
I'm looking for guidance on why the AttackArea might be monitoring for collisions even before an attack is initiated and how to ensure it's only activated upon pressing the attack button. Any insights or suggestions for further debugging this issue would be greatly appreciated.

Thank you for your time and help!

(and yeah this is my first time posting her so i got chatGPT to write this since it'll explain the issue better)

  • xyz replied to this.
    func _on_EnemySoldier_area_entered(area):
        if area.is_in_group("player_attacks"):
            take_damage(30)

    Worth starting here debugging what area has entered and if it is correctly assigned (or not) the group you expect.

    e: just a sec - what’s monitoring what here? You’re toggling the player area monitoring? Maybe you should ask why that’s expected to have any effect on an enemy? Perhaps you mean monitorable.

    buzzbuzz20xx Never call yield() from perpetual callbacks like _process(). Rebuild your system in a way that doesn't use it.