Player won't take damage went hit by enemy

Godot Version

Godot 4.3

Question

im very new to godot/programming in general and I’ve been looking through some tutorials, I’ve seen GDQuests “Your First 2D GAME From Zero with GODOT 4! Vampire Survivor Style” and wanted to make it so instead of my character taking a const DAMAGE_RATE of 5 i wanted the damage to come from the enemy attacking so i found branno’s vampire survivor guide but when i tried adding in the hurtboxes and hitboxes branno talked about the player character doesn’t take damage, I can provide any of my code needed

Can you give a link to Branno's vampire survivor guide and the timestamp of where you would add the hurtboxes and hitboxes? Alternatively you can share your scene setup and code.

The player not taking damage can be any number of things:

  • The enemy attack function fails and does nothing
  • The attack doesn’t reach the player
  • The attack reaches the player, but there’s no collision
  • The attack collides with the player, but there’s no signal
  • The attack does send a signal to the player, but there’s no algorithm to deal with the attack properly

Learn about breakpoints and apply them to see what happens when the enemy attacks

This is the part in the video

Here is the Enemy Scene:

Here is the Player Scene:

That should be all relevant scenes and code is anything else is needed I can provide it

I wish I could’ve done that all in one message but since I’m new I couldn’t so sorry about the spam

Try make all in one post.
put code in

```
Code
```

you can use for this
obraz

1 Like

Ok will do thank you, im new to this forum so this helps

1 Like

Enemy Code:

extends CharacterBody2D

@onready var movement_speed = 200
@onready var player = get_tree().get_first_node_in_group("Player")
#@onready var stats = $Stats
@export var health = 3

func _ready():
	%BlueSlime.play_walk()

func _physics_process(delta):
	movement()

func movement():
	var direction = global_position.direction_to(player.global_position)
	velocity = direction * movement_speed
	move_and_slide()

func _on_hurtbox_hurt(damage):
	health -= damage
	%BlueSlime.play_hurt()
	if health <= 0:
		queue_free()

Player Code:

extends CharacterBody2D

signal health_depleted

var health: int = 100
@export var movement_speed = 600
#@onready var stats = $Stats

func _physics_process(delta):
	movement()

func movement():
	var direction = Input.get_vector("move_left", "move_right", "move_up", "move_down")
	velocity = direction.normalized() * movement_speed
	move_and_slide()


func _on_hurtbox_hurt(damage):
	health -= damage
	print(health)

Hitbox Code:

extends Area2D

@export var damage = 0
@onready var collision = $CollisionShape2D
@onready var disableTimer = $DisableHitBoxTimer

func tempdisable():
	collision.call_deferred("set","disabled",true)
	disableTimer.start()

func _on_disable_hit_box_timer_timeout():
	collision.call_deferred("set","disabled",false)

Hurtbox Code:

extends Area2D

@export_enum("Cooldown", "HitOnce", "DisableHitBox") var HurtBoxType = 0

@onready var collision = $CollisionShape2D
@onready var disableTimer = $DisableTimer

signal hurt(damage)

func _on_area_entered(area):
	if area.is_in_group("attack"):
		if not area.get("damage") == null:
			match HurtBoxType:
				0: #Cooldown
					collision.call_deferred("set", "disabled", true)
					disableTimer.start()
				1: #HitOnce
					pass
				2: #DisableHitBox
					if area.has_method("tempdisable"):
						area.tempdisable()
			var damage = area.damage
			hurt.emit(damage)

func _on_disable_timer_timeout():
	collision.call_deferred("set", "disabled", false)

On your Area2d
obraz

This signal what you needed use.
you check if body have method like hurt_player (or any name you want) and call that method.

in that scenario if im not using the hurt(damage) custom signal made how am i supposed to get the damage value of the enemy thats hitting the player?

you hurt_player method can accept numbers
then you call hurt_player with integer and you will call something like hurt_player(5) you needed only one signal, that’s make you code more readable

so the hurt_player function would be something like this

func hurt_player(value):
	health -= value
	print(health)

while the enemy hitbox im assuming would have code looking like this

func _on_hitbox_body_entered(body):
	if body.has_method("hurt_player"):
		body.hurt_player(3)

Yes something like this you can also lock value variable to int only (A built-in type for integers.) or floats.

i got 2 last questions then i should be good,
is the Hitbox and Hurtbox code i showed above needed at all?
and
how would i get the player to take continuous damage instead of just getting hit once?

you can make timers, you can count time, you can make timers manually with delta time and use _physics_process
you can make effects nodes who will stack in player. there lots of options.
they will stack they will stop after player leave area or just over time etc.

for new devs I can recommended @Brackeys https://www.youtube.com/@Brackeys he just start Godot tutorials, sadly he isn’t so active.

I’ll look into those and check out Brackey, Thank you so much for helping

you can create node on player with “Damage over Time” and you will not be limited to one and destroy after finish :slight_smile: and there’s Tweens too, they can be used for run method after time and create how many needed in loop, and there’s even looping option :smiley: . and you can kill tween early before time finish.
in scenario player on fire but player use water…

ill go look up a tutorial on tweening and see if i can implement that somehow

your basic tween could look like this

var tween = get_tree().create_tween()
tween.set_loops(4)
tween.tween_callback(body.player_hurt(3)).set_delay(2)

I dint test that because I’m more C# user of Godot
for reference here is Tween docs Tween — Godot Engine (stable) documentation in English