Godot Version
Replace this line with your Godot version
Question
So I have this code for the hitbox and hurtbox:
Apologies for the whacky code
Hitbox:
@export var damage: int = 1 : set = set_damage, get = get_damage
@export var stagger: Stagger
@export var stagger_damage : bool = false
@export var active : bool = false : set = set_active
@export var launch : bool = false
@export var knock_back : bool = false
@export var launch_strength : float = 40.0
@export var knock_back_strength : float = 100.0
@onready var shield_hit : bool = false
func _ready():
connect("area_entered", _on_parried)
func set_active(_value:bool)->void:
active=_value
func set_damage(value: int):
damage = value
func get_damage() -> int:
return damage
func _on_parried(_area :Area2D) -> void:
if _area!= null:
if _area.is_in_group("hitbox"):
damage = 0
knock_back = false
launch = false
clashed.emit()
elif _area.is_in_group("player_hitbox"):
damage = 0
knock_back = false
launch = false
if _area.knock_back:
clash_knock_back.emit(_area.knock_back_strength)
elif _area.launch:
clash_launch.emit(40)
else:
clashed.emit()
elif _area.is_in_group("ParryBox"):
#print_debug("parried!")
stagger.stagger -= 1
parried.emit()
else:
pass
Hurtbox:
class_name HurtBox
extends Area2D
signal received_damage(damage: int)
signal received_stagger_damage(damage: int)
signal got_hit(hitbox: HitBox)
signal bullet_hit(_damage: int)
signal parried()
signal weakpoint_hit()
signal launched(launch_strength : float)
signal knockback(knock_back_strength : float)
@export var health: Health
@export var stagger: Stagger
@export var dmg_mult : int = 1
@export var weakpoint : bool = false
@onready var total_damage : int = 0
@export var shielded : bool = false
func _ready():
connect("area_entered", _on_area_entered)
#connect("area_entered", _on_parried)
connect("body_entered", _bullet_hit)
func _on_area_entered(hitbox: HitBox) -> void:
if not hitbox.active:
return
elif health.health<=0:
return
else:
if hitbox != null:
#print(hitbox.knock_back)
if hitbox.launch:
launched.emit(hitbox.launch_strength)
if hitbox.knock_back:
#print("KNOCKING BACK")
knockback.emit(hitbox.knock_back_strength)
if hitbox.is_in_group("spc_atk"):
weakpoint_hit.emit()
if hitbox.stagger_damage:
stagger.stagger -= (hitbox.damage * dmg_mult)
### Maybe add minimum health damage to stagger attacks?
#print_debug(hitbox.damage, " ",dmg_mult)
#received_damage.emit(hitbox.damage)
got_hit.emit(hitbox)
else:
if weakpoint:
health.health -= (hitbox.damage * dmg_mult)
stagger.stagger -= (hitbox.damage * dmg_mult)
#print_debug(hitbox.damage, " ",dmg_mult)
received_damage.emit(hitbox.damage)
got_hit.emit(hitbox)
else:
if not shielded:
health.health -= (hitbox.damage * dmg_mult)
#print_debug(hitbox.damage, " ",dmg_mult)
received_damage.emit(hitbox.damage)
got_hit.emit(hitbox)
func _bullet_hit(_rigid_body : RigidBody2D) -> void:
var _damage : int
if _rigid_body.has_method("get_damage"):
_damage=_rigid_body.get_damage()
else:
_damage=1
if health.health<=0:
return
_rigid_body.hard_impact()
if stagger.stagger>0:
stagger.stagger-=1
else:
health.set_health(health.health-1)
print_debug(health.health)
#received_damage.emit(_damage)
bullet_hit.emit(_damage)
received_damage.emit(_damage)
_rigid_body.impact()
func set_damage_mulitplyer(value:int):
dmg_mult=value
func get_damage_mulitplyer() -> int:
return dmg_mult
When hitbox and hurtbox, the character its attached to gets damaged. To keep from taking damage due to hitbox detecting collision every frame, I use this signal:
#print(hit_buffer.time_left)
if not hitbox.active:
return
else:
#assert(hit_buffer.is_stopped()==true)
#assert(hit_buffer.time_left<=0)
hit_buffer.start(1)
hitbox.active=false
hit_sound=hit1
AudioStreamManager.play(hit_sound)
#hb_collision.disabled
hb_collision.set_deferred("disabled", true)
hit_fx.visible=true
hit_fx_player.stop()
hit_fx_player.play(hit_animation)
First I used “hb_collision.disabled” (the collisionshape for the hitbox) but was getting errors, so I switch to "“hb_collision.set_deferred(“disabled”, true)”, which got rid of the errors, but the hitbox still collided many times before disabling, instead of disabling on first collision.
Right now I’m trying to use an “active” flag on the hitbox, but it still sometimes hits a couple times before disabling. Anyone got any tips on the best ways of disabling hitbox on first collision?