My Hurt Box isn't working

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By javrocks

Whenever i instance the scene it tells me that hitpoints is 100 but when a shape enters the hurt box instead of only subtracting 50 from max hitpoints the signal keeps emiting and keeps on subtracting 50 even though the shape has left the hurt box

I tried to change signals and turn on/off layers and masks so that the signal would only emit once but nothing seems to be working

extends KinematicBody2D

 export(int) var hitpoints = 100
 var max_hitpoints = hitpoints

func _ready():
   print (hitpoints)

func _on_Hurtbox_body_shape_entered(body_id, body, body_shape, local_shape):
	OnHit()

func OnHit():
   hitpoints -= 50
   $TextureRect.set_percent_value_int(float(hitpoints)/max_hitpoints * 100)
   if hitpoints <= 0:
	  queue_free()
   print (hitpoints)

Code seems ok to me, so likely something to do with the setup of the scene itself. One thing you could try is to change damage to reduce smaller number and check how many times signal triggers. Maybe you have multiple bodies entering hurtbox at the same time.
Second thing, you might want to add invincibility frames after being hit, which bypasses the problem altogether (altough it’s better to check what causes it so that random glitches won’t creep up later) :slight_smile:

aXu_AP | 2021-10-20 20:11

:bust_in_silhouette: Reply From: DaddyMonster

OnHit (godot_is_snake_case) is called when there’s a collision so it’s going to be called repeatedly.

Just add is_hit = false as a member variable to the top.

And then:

func on_hit():    
    if not is_hit:
        is_hit = true
        your_code

This is what i"ve changed and it still doesn’t work. It keeps emiting more that once

extends KinematicBody2D

export(int) var hitpoints = 100
var max_hitpoints = hitpoints

var is_hit = false

func _ready():
   print (hitpoints)

func _on_Hurtbox_body_shape_entered(body_id, body, body_shape, local_shape):
   OnHit()

func OnHit():
 if not is_hit:
    is_hit = true
 hitpoints -= 50
 $TextureRect.set_percent_value_int(float(hitpoints)/max_hitpoints * 100)
 if hitpoints <= 0:
    queue_free()
  print (hitpoints)

javrocks | 2021-10-20 23:04

Just indent from hitpoints -= 50 down

Oh, forgot to say you’ll need logic to reset is_hit back to false if there’s no collision.

DaddyMonster | 2021-10-21 08:41

How would u reset is_hit ???

javrocks | 2021-10-21 12:47

Well, that depends. How do you want your game to behave? You could use a timer so you slowly take damage in the area, you could make an outer reset area, you could check whether its a different area if you have several, you could reset it on distance, you could check for collisions and reset if there isn’t one… More than one way to skin a cat.

Your game, your rules. :slight_smile:

DaddyMonster | 2021-10-21 13:25