Checking for melee attacks

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By PMurrayDesign
:warning: Old Version Published before Godot 3 was released.

I’m trying to code in some simple melee attacks for my player but I’m not exactly sure of the best way to set the player up and check for collisions. I’ve checked out some examples but they all seem to focus on projectiles.

Currently I have an Area2D that sticks out in front of the player representing their attack box, and am checking for collision with enemies via an _on_*_area_enter function within the enemy script. Currently this just reduces the opacity of the enemy when they collide so I can test.

This works, but I can’t figure out how to only reduce the opacity only when the player is attacking. I’ve tried checking to see if the player attack state variable is true via .get() but the area_enter doesn’t seem to acknowledge or care about this state. Is this possible, or does the area_enter function run regardless?

Or, should be checking for collisions via the attack box Area2D rather than in the enemy script and checking to see if the enemy Area2D has a “take_damage” method and calling that like in the examples? I tried this approach originally but couldn’t seem to get the method to call, and Godot gave no errors so I tried a different route.

Thanks.

:bust_in_silhouette: Reply From: eons

I assume the attacker receives the attack signal:

Play with area layer mask values, turn all off by default, then on while attacking.

Or can ignore area_enter when not attacking (if attacking: area.hurt()).

Depending on the type of attack you can use a raycast too (or a group of rays) could be easier to use with an animation.

:bust_in_silhouette: Reply From: Warlaan

You can use animations to animate pretty much any property, including the “monitoring”-flag of an area.

I would recommend switching off the monitoring flag by default and only switching it on during the attack animation. That should suffice, since afaik objects inside the area are reported as “entering” when the area is switched on.

This worked beautifully. I had a attacking boolean that was checked in the on body enter method but I now understand that its only called once when something IS entered. Im using a timered to set monitoring back to false in a few miliseconds

Chevon | 2020-09-09 04:27

:bust_in_silhouette: Reply From: avencherus

You need to actively poll for such events in some way, flagging the enemies. The entering and exiting of an area only happens as a single event. You have to combine that information.

Just an pseudo example of what you might consider, here I keep an array of enemies that may enter or leave the hit area, and when the attack key is hit, a function they have for taking damage is called.

extends Node2D

var targets_in_range = []

func _ready():
	set_fixed_process(true)
	
func _fixed_process(delta):
	if(Input.is_action_just_pressed("my_attack_button")):
		for enemy in targets_in_range:
			enemy.deal_damage(100)

func on_exit_strike_range(target):
	for n in range(targets_in_range.size()):
		if(targets_in_range[n] == target):
			targets_in_range.remove(n)
			return

func on_enter_strike_range(target):
	targets_in_range.push_back(target)

Thanks guys, Warlaan’s suggestion for animating the monitoring flag works perfectly, I didn’t realise a solution would be that simple. I think I’ve just understood why Godot development can be so quick.

PMurrayDesign | 2016-11-13 09:48

Even if you want to have a list of all objects inside the area you can just use the get_overlapping_bodies()-method.
( Area2D — Godot Engine (stable) documentation in English )

Warlaan | 2016-11-13 10:07