Target lock with instanced enemies

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

Hi there,
On My Player have Area node and it can detect the enemies that
Entered inside.

What im Trying to Do is, lock to target (Player face the target and stayy locket Even if itself move) The more close one that insade the Area.

But My enemies Get instance at the main scene more then once, So i did use a group
Named “enemy” to Get enemies.
But still did not work.
I did work on vector.distance_to and look_at to solve this issue and Failed To Do So.

So i need help, same or diffrent kind of view and an example syntax.
Thank you, and sory for Bad gramer.

HI morningkingdom.

Can you share the code that you have now so we can see if we can find the problem?

This question has a working example.

If you have multiple enemies and you need to pick the closest, you will need the distance to each of them. You can use a Vector2 (or Vector for 3d) = player.position - enemy.position and call the length method on that vector to get the distance, then pick the closest.

AndyCampbell | 2020-11-12 20:48

Thanks for anwser, well because of a less busy “day job” i had today, i thought about this problem, and kind of solve it, this is the code i came up with, this code is on the player node:

func _on_Enemy_Detect_body_entered(body):
	body = enemy1
	var min_distance = 999
	var lock_enemy
	var instanced_enemies = get_tree().get_nodes_in_group("enemy")
	if body == enemy1:
		print ("enemy entered the area")
		for close_enemy in instanced_enemies:
			var distance = translation.distance_to(close_enemy.translation)
			if (distance < min_distance):
				lock_enemy = close_enemy
				print ("close enemy :  " +str(lock_enemy), "and dinstance from it:  " +str(distance))
				look_at(lock_enemy.translation,Vector3.UP)
	else:
		enemy1 = null

this is the output:

enter link description here

well, i think i got the closest enemy but things got messier when it came to do lock the enemy part, because what i wanna do is, this :

(i have great paint skils)

well im new at geme dev, and codding, so i need help guys. what should i do with this?

morningkingdom | 2020-11-13 17:54

:bust_in_silhouette: Reply From: AndyCampbell

The video looks really nice. I think I understand what you are trying to do - I think you are very close.

The function you wrote above will get called once for each enemy which enters the detection area. If you want a continual lock, you need to run look_at every frame so the player continues to look at the enemy, right?

I assume your enemy1 variable is intended to be the closest enemy that you are locking to - is that correct?

So, I suggest you “use func _on_Enemy_Detect_body_entered(body):” ONLY to select the closest enemy and store that. So, remove the look_at call from that function. This function should update a variable which is a reference to the closest enemy (is that what you intend enemy1 to be?)

Your look_at should be moved to somewhere called called from either _process(delta) or _physics_process(delta): (depending on which you are using). That logic should also handle the case where the closest enemy has been removed (for example queue_free) and reset the closest enemy reference back to null. Also, you probably want to check the max_distance in the new function as well so the lock will break if the enemy gets too far.

If another enemy enters the Enemy_Detect area and this new enemy is closer, that will update the closest enemy variable to point to the new enemy.

For now, i solve the main issue

var lock_enemy
var lock_enemy_check = 0

func _physics_process(delta):

if lock_enemy:
	look_at(lock_enemy.translation,Vector3.UP)
	if lock_enemy_check == 1:
		rotate_speed = 3


func _on_Enemy_Detect_body_entered(body):
	body = enemy1
	var min_distance = 20
	var instanced_enemies = get_tree().get_nodes_in_group("enemy")
	if body == enemy1:
		print ("enemy entered the area")
		for close_enemy in instanced_enemies:
			var distance = translation.distance_to(close_enemy.translation)
			if (distance < min_distance):
				lock_enemy = close_enemy
				print ("close enemy :  " +str(lock_enemy), "and dinstance from it:  " +str(distance))
#				look_at(lock_enemy.translation,Vector3.UP
				lock_enemy_check = 1
	else:
		enemy1 = null

this is output:

https://streamable.com/8bgjog

as you can see, because of lock, and little collisions of between enemy and player, all of the objects on the scene goes of of their axis, is there a simple and clean way the fix this?. i mean i dont need collisions in this game, this will be top down, so all the objects need to be on the floor, not float around at the y axis.they will just shoot the eachother.

well maybe its because of my way of player controller mechanic, its roughly like this:

export var speed = -0.5
export var speed2= 0.5
var rotate_left
var rotate_right
var moveForward
var rotateValue
var moveBack
var rotate_speed = 0.2

func _physics_process(delta):

rotate_left = Input.is_action_pressed("left")
rotate_right = Input.is_action_pressed("right")
moveForward = Input.is_action_pressed("up")
moveBack = Input.is_action_pressed("down")

if rotate_left:
	rotateValue = -speed * rotate_speed
	rotate_y(rotateValue)
if rotate_right:
	rotateValue = speed * rotate_speed
	rotate_y(rotateValue)

if moveForward:
	translate(Vector3(0,0,speed))
if moveBack:
	translate(Vector3(0,0,speed2))
	
	

i will make this game for phones so i will add a joistic mechanic, because of that i will change the character movment mechanics too, but i need to know, that floating at the y axis thing happinig because of the movment of the player?

thank you for your time.

morningkingdom | 2020-11-14 18:29

I found the reason, because of raycasts.
Because of both enemy and player has raycast, and they both lock eachother, when they lock, even if there will be little bit of “y” axis valuse on either of them, they start get of the axis, and it goes bigger and bigger each frame. soo i decided that i should try diffrent way for aim lock, not use look_at, well we will see.

morningkingdom | 2020-11-17 16:38