How to target-lock and switch between them in a good way

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

Hello.
So Im trying to make a tab-target system for my 3D project.

If there is just one enemy, my code work. My character can lock-on and off. My camera and character is pointed to the target.

But I cant work out what to do if there is more than one target.

I have a node with enemies as child_nodes.

I can detect the nearest enemies with my var closest_distance.

Ive tried to use a ray-cast, but it wasnt so good.
Ive tried to use array, but i dont know how to make it work like I want.

Here is my code:

	if lock_on_active:
	
	
	if Input.is_action_just_pressed("gp_swich_lock"):
		var allenemies = get_node("../../ENEMIES")
		if closest != null :
			if allenemies.get_children().size() == 2 and allenemies.global_transform.origin.distance_to(global_transform.origin) < closest_distance:

				if closest.get_index() == 0:
					closest = allenemies.get_child(1)
					lock_on_target = closest
				else:
					closest = allenemies.get_child(0)
					lock_on_target = closest

			if allenemies.get_children().size() == 3 and allenemies.global_transform.origin.distance_to(global_transform.origin) < closest_distance:

				if closest.get_index() == 0:
					closest = allenemies.get_child(1)
					lock_on_target = closest
				elif closest.get_index() == 1:
					closest = allenemies.get_child(2)
					lock_on_target = closest
				else:
					closest = allenemies.get_child(0)
					lock_on_target = closest

			if allenemies.get_children().size() == 4 and allenemies.global_transform.origin.distance_to(global_transform.origin) < closest_distance:

				if closest.get_index() == 0:
					closest = allenemies.get_child(1)
					lock_on_target = closest
				elif closest.get_index() == 1:
					closest = allenemies.get_child(2)
					lock_on_target = closest
				elif closest.get_index() == 2:
					closest = allenemies.get_child(3)
					lock_on_target = closest
				else:
					closest = allenemies.get_child(0)
					lock_on_target = closest

			if allenemies.get_children().size() == 5 and allenemies.global_transform.origin.distance_to(global_transform.origin) < closest_distance:

				if closest.get_index() == 0:
					closest = allenemies.get_child(1)
					lock_on_target = closest
				elif closest.get_index() == 1:
					closest = allenemies.get_child(2)
					lock_on_target = closest
				elif closest.get_index() == 2:
					closest = allenemies.get_child(3)
					lock_on_target = closest
				elif closest.get_index() == 3:
					closest = allenemies.get_child(4)
					lock_on_target = closest
				else:
					closest = allenemies.get_child(0)
					lock_on_target = closest
				
:bust_in_silhouette: Reply From: Inces

You definitely need to use array and for loop through it.

It can be enemies.get_children() or get_nodes_in_group(“enemies”) or get_overlapping bodies within collision shape of your players vision/range. Sorting this array according to proximity is a little tricky, enemies would have to have their own variable which updates their distance to player. Lets call it distancetoplayer. You will use sort_custom() on this array a.distancetoplayer > b.distancetoplayer, cehck it in documentation. Finally :

func() inputevent :
      if input is pressed Tab :
             For enemy in alreadysortedarray :
                    if lockontarget==null or lockontarget=alreadysortedarray[alreadysaortedarray.size()-1]:
                            lockontarget = alreadysortedarray[0]
                     else:
                            lockontarget = alreadysortedarray.find(lockontarget + 1 )
 

sorry for messy code, I hate this websites interface. What happens there is after pressing tab, if enemy is already focused - focus next closest. If no enemy is focused or last enemy is focused - focus first enemy in array, meaning closest

Either put enemies in a group and have a variable dedicated to cycling to targets

var enemes:Array = 
var i :int = 0

if (Input.is_action_just_pressed):
    i+=i
    enemies[i%enemies]