How to constantly check if something is overlapping with an Area2D node

Godot Version

4.6.3

Question

I don’t know if this question has been answered for my specific case but I’ve been working on hit-boxes and hurt-boxes and I was able to get them to work, it’s just that when my player is constantly overlapping with the hurt-box it doesn’t re-trigger area_entered signal. Is there a way to re-trigger area_entered and/or constantly check if the hit-box is overlapping with the hurt-box?

Yes, but it’s easier with a ShapeCast2D if you need continual checks.

how would that vary compared to area2D? (still very new to Godot)

Areas have get_overlapping_areas() method you can continually call.
Alternatively you can maintain your own boolean flag you set on entered signal and reset on exited signal.

More lines of code. Area2D is typically used to detect entry and exit into it. ShapeCast2D is used to check for collisions every frame.

As @normalized points out, there are a number of solutions to your problem. The boolean being the easiest.

how would that look like?

(Re)set the flag in your signal handles and check its value in your processing function.

the best thing I can think of is:

func _process(_delta: float) -> void:
	for overlapped_area in get_overlapping_areas():
		if overlapped_area is Hitbox:
			if health_component.can_be_damaged:
				health_component.health_values.damage(overlapped_area.damage)
extends Area2D

var is_colliding: bool = false


func ready() -> void:
	body_entered.connect(_on_body_entered)
	body_exited.connect(_on_body_exited)


func _on_body_entered(_body: Node2D) -> void:
	is_colliding = true


func _on_body_exited(_body: Node2D) -> void:
	is_colliding = false

its working but I don’t have a way (that I know of) to get the damage value from the hurt-box

I’ve tried referencing it on ready but gives nil

dragon’s code work somewhat but I don’t have a way (that I know of) to get the damage value from the hurt-box

I’ve tried referencing it on ready but gives nil

Get it from the signal argument that you receive in _on_body_entered()

like?

func _process(_delta: float) -> void:
	if is_colliding == true:
		if health_component.can_be_damaged:
		   health_component.health_values.damage(area_entered.get_object().damage)

I work better with visuals, sorry I didn’t clarify (words don’t help my tism brain much)

Code is not a visual. It’s also words.

Here:

func _on_body_entered(_body: Node2D) -> void:
	is_colliding = true

_body is what collided. If that’s a hurtbox, get whatever you need from it and store it in some custom property you can inspect/use in _process(). The same principle you’re already doing with that boolean flag.

what i mean by visual is the code and text is just typing what I should do, the main thing that I’m asking is just how to structure it to fit my hit-box code with a code visual because vague/loose text answers don’t help me much to understand.

in other words, I don’t know how to store it in a custom property from the signal and don’t know how to structure the process function for it to work with the examples y’all shown cause I’m still relatively new to Godot

Same as vague/loose questions don’t help in understanding the problem. How could anyone tell you how to fit something into your hitbox code when you haven’t posted any of it?

class_name Hitbox extends Area2D

@export var health_component: HealthComponent

func _ready() -> void:
	monitorable = false
	area_entered.connect(_on_area_entered)

func _on_area_entered(_area: Area2D) -> void:
	if _area is Hurtbox:
		if health_component.can_be_damaged:
			health_component.health_values.damage(_area.damage)

I was kind of expecting a universal answer with the hope someone asked a very similar question (like 98% similar) and someone would be like boom here it is but life an like that. i’ll show code next time instead of expecting extreme clairvoyance and foresight from everyone

I actually have answered this question a number of times before, but without specifics it’s really hard to know what exactly you want. Also most people use body detection instead of hurt boxes. And well, I had stuff going on today.

So first off, you are checking if the Area2D you encounter is a Hurtbox object. That’s fine, but you don’t need to do that. If you add the Hitbox object only to the Physics Mask that the Hurtbox is on, then that check is done for you by the physics engine, and its much faster than your class type check in code. It also means your code runs much less frequently. Likewise, if you don’t put your Hitbox on any Physics Layers, then you don’t need to set monitorable = false, because it already isn’t detectable.

While we are at it, I recommend renaming your HealthComponent to Health. I why in a post I made yesterday about an Experience component, walking through the reasoning and code step-by-step.

I also discuss how to build and use a Health component here:

So with that in mind, while I’m not going to change your class name (I leave that to you) I am going to change your variable name for readability. I also recommend you change the implementation to directly call health.damage() and hide the implementation details of health_values, whatever that is. (Again, more code would have been helpful.) Along those lines, you’d be better off just calling damage() and letting the Health component check if it can be damaged.

I also changed _area to area. Because prepending a variable with an underscore in an arguments list means you aren’t going to use it, and avoids compiler warnings.

class_name Hitbox extends Area2D

@export var health: HealthComponent

var hurt_box: Hurtbox


func _ready() -> void:
	area_entered.connect(_on_area_entered)
	area_exited.connect(_on_area_exited)
	set_process(false)


func process() -> void:
	if health.can_be_damaged:
		health.health_values.damage(hurt_box.damage)


# Notice the type checking I'm doing in the argument.
func _on_area_entered(area: Hurtbox) -> void:
	hurt_box = area
	set_process(true)


func _on_area_exited(_area: Area2D) -> void:
	hurt_box = null
	set_process(false)

Also, without seeing your scene tree, I can’t be sure, but I think you have your names for Hitbox and Hurtbox reversed. The Hitbox is attached to the weapon, and the Hurtbox to the thing you are damaging. So the Hurtbox shouldn’t know how much damage is being dealt.

Anyway, that should help.

Thank u for the visuals and sorry if I was difficult I’m mainly a visual and hands on learner. I was just getting frustrated with the minimal code visual and not knowing what to do with it (started godot a week and a half ago)

No worries. Hopefully you learned both how to solve your problem and how to ask questions to get better (and faster) answers in the future.