1
\$\begingroup\$

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:


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)

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

It is a quirk of Godot that physics object can interact when they enter the scene tree. To prevent that you need to set monitoring to false even before that.

You can do so by setting the monitoring to false in the inspector. Or if that is not viable, you can do it in _init.

And since you would be setting monitoring to false early, you would need to do it in _ready.


Futhermore, I think handle_attack_input does not need timer nor disable monitoring, since you are already doing that when the animation finishes...

Unless you are trying to define a portion of the animation in which it can cause damage, in which case the reponsability of disabling monitoring should not be when the animation finishes.


Your code for the Area2D seems take damage when an enemy enters, instead of imparting damage to the enemy. Futhermore, it removes the Area2D (with queue_free). You might want to review that.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .