Please help with targeting

Godot Version

4.2.1

Question

i dont really know how to provide more details for this and it kinda confuses me myself so.

the code is used to send a damage signal to the enemy

func _attack() → void:

var potential_enemies := get_overlapping_areas()
if potential_enemies.is_empty() == false:
	
	for enemy in potential_enemies:
		enemy.emit_signal("hit", damage)
		print("attack")
		if animations == null:
			pass
		else:
			animations.play("attack")
		break

so basically its a for loop but it only activates once and yeah its kind of weird.
it attacks one enemy and it will attack that enemy until the enemy dies and it will never change targets.
is there a way that i can make it so it will attack the nearest target. basically what will happen is the ai will get to the base and it will lock onto the base and keep attacking it and since it has high health it will just attack the base and be defenseless. i want to make it so it will attack the closest enemy so that it wont lock onto the base and frustrate players

i know i didnt provide much information but please ask for anything and ill provide it sorry i just dont know what to provide

# Let's start with a null target and a very large distance.
var target = null
var target_distance := 1000000000000.0

# If an enemy is closer than the current target, update the values.
for enemy in get_overlapping_areas():
    var enemy_distance := position.distance_squared_to(enemy.position)
    if enemy_distance < target_distance:
        target = enemy
        target_distance = enemy_distance

# If a target is found, attack it.
if target:
    target.emit_signal("hit", damage)
    ...

I’m using distance_squared_to() instead of distance_to(), because it runs faster, and the actual distance isn’t needed for comparison.

Also, the way you’re using signals unnecessarily complex. You could just define a damage function for the enemies.

target.take_damage(damage)
1 Like

thanks a lot. It took me like 15 minutes because it wouldn’t work, but I just did (enemy.get_parent().position), and then it worked perfectly. will this be okay?

If it works, it’s ok, but it’s recommended to use enemy.global_position instead.

1 Like

Okay, thanks. I did that. how does global position differ from getting the parent, and how does it make the code better or something?

position is relative to the position of a node’s parent, whereas global_position is relative to the scene’s origin at (0, 0). Let’s say your scene tree looks like this:

  • Parent
    • Child

If you set $Parent.position = Vector2(1, 1), both nodes will move to (1, 1). However, if you print $Parent/Child.position it will – unlike $Parent/Child.global_position – still be at (0, 0).

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.