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.