• Building
  • Checking for an Area2D node optimization

Hey, I want to start with saying that I'm brand new to Godot and somewhat new to programming as well, so please talk to me like I'm 5 years old :)

I was following a tutorial on hurtboxes and hitboxes on YouTube and the video was showing that you should create a hurtbox and hitbox scene and then add the hitbox scene on the player scene and the hurtbox scene to the enemy scene to check for attacks.

In code, the video showed how to use the signal "area_entered" on the script attached to the enemy to check for a collision (and there were multiple instances of the enemy scene in the world scene).

My question is, wouldn't it be more efficient to have the player hitbox check for other hurtboxes rather than having all the hurtboxes check for just one hitbox? If so, how would it look in code?

Welcome to the forums @Pillowbottom!

To answer your question: it depends but generally it would be more efficient to have the player hitbox check rather than every enemy. This is because for every collision with an Area node, the Area/Area2D node will emit the signal and the function will be called. If two enemies collide with each other, their hurtboxes will both emit the signal, the code will check if it's the player (I presume) and then nothing will happen. This condition, while quick and short, does take a bit of processing power. In contrast, if it was on the player, then whenever the player collides with an Area, it emit its signal and the processing will happen there.

It is generally more efficient when on the player because, generally speaking, the player is has the most collision detection conditions where it needs to know about what it has collided with. You generally do not care about enemies hitting each other or overlapping, so not emitting signals there means you save a bit of performance when this occurs by not needing to do needless checks. Granted, you still have to do these checks for the checks when the player collides with an enemy, but this is the case regardless of where the signal is.

One thing to note though: It's not always more efficient to put it on the player! If you have many areas in a scene and the player collides with a bunch of them without needing to interact with them, then it could be less efficient than having the enemies process the collisions.

Finally, one last note: For the most part it really doesn't matter too much. Performance for these kinds of things are generally not the bottleneck if there is performance issues. Instead it is generally that some performance heavy operation is called rather than a quick condition/signal. So, while it is likely more efficient to have the player do the processing, I wouldn't sweat it too much either way :smile:

If so, how would it look in code?

I'd say it depends on the setup, but here's kinda how I imagine it would look in the player script:

var player_health = 3

func _ready():
	get_node("hitbox").connect("area_entered", self, "on_area_entered")

func on_area_entered(other_area):
	# check if the thing we collided with has a function called
	# on_collide_with_player. If it does, then call it!
	if (other_area.has_method("on_collide_with_player") == true):
		other_area.on_collide_with_player(self)

# example function
func hurt_player(amount):
	health -= amount
	print ("health is now: ", health)

and then in the enemy script:

func on_collide_with_player(player_node):
	player_node.hurt_player(1)

@TwistedTwigleg thanks a lot for your thorough answer! It makes sense to me now :)