Stuff for Enemies

Godot Version

`4.2.2

Question

How to make it so that if you have an enemy and if you touch that enemy on the side you die, but if you touch it on the head the enemy will die.

I saw an idea for this which was to compare the character global position with the enemy upon colliding and see if the character is higher than the enemy.
Or I believe you can use the normal which is reported upon colliding to determine which direction it is

2 Likes

You could give the enemy two area2Ds. One to receive damage (lead) and the other to damage the player(Side). Thats how I would do that.

2 Likes

you need to check an angle of 2 Vector2 positions using

var enemy_pos:=enemy.global_position
func check_angle(enemy_pos)->void:
	const ATTACK_THRESHOLD:=100.0
	var self_pos:=global_position
	if self_pos.distance_to(enemy_pos)<ATTACK_THRESHOLD:
		var self_angle:float=rad_to_deg(self_pos.angle_to_point(enemy_pos))
		if self_angle>80.0 and self_angle<100.0:
			kill(enemy)

and distance every process frame or do cached checks with timer. If you can and know how to avoid colliders its better to not use them

1 Like

Why is it better not to use colliders in this case?

1 Like

because it has direction, not just “on touch”, or you need an extra collider on top of enemy.
In my approach, if player not inside of 80-100 angle threshold, player could be killed using additional else: kill(player)

1 Like

I think both approaches have their merrits, which is best will depend on you and your game.

Games like Mario, where characters are quite small on screen and collisions are simple (probably) use a directional method like @solver10 and @jomi described, or a similar method of comparing the (PhysicsBody) collision angle against an up vector using dot product.

Games like Street Fighter or Smash Bros where characters are large and/or collisions are complex, or any shooter that includes headshots or weak points, will use something similar to @hydraware’s suggestion (hitboxes and hurtboxes).

I’m gradually learning that there is often no one right solution, and if there is, it’s just the one you’re most comfortable implementing and maintaining.

1 Like

when talking about hitboxes, checking distance is the same thing as checking sphere, without actual sphere mesh. So if you try to think that way, there many ways to do simple checks without taking into account their complex forms and get same and fast result :wink:

1 Like

True, you can check a collision between two spheres that way. It’s probably what CollisionObject2Ds do internally when checking circle against circle. I was referring more to the usage though: one collision shape (or equivalent distance check) and an angle, or multiple collision shapes with different purposes. Each approach is useful for solving a different set of problems.

But I wouldn’t necessarily say it’s better than adding a collider at the top, it’s just different ways of approach.

Unless there is a performance benchmark that shows your approach is faster, which, to be honest, I don’t think is the case, using a collider in this specific instance is unlikely to cause any serious performance issues. Personally, I would recommend using an Area2D at the top and leveraging the signal, especially for someone who is still learning, as it is more visual.

1 Like