Find Target From List

Hi there Unity,

I’m having trouble consistently pulling my desired target from a list. Here’s what I’ve set up.
This is for a tower defense game, and the tower has two main settings. First and Last. As you can imagine, this sets the tower to either attack the first target in the list, or the last in the list. The targets are spawning and then running through a maze to the end zone.

  1. Target spawns and gets added to list
  2. If target dies, it gets subtracted from list.

The tower starts out (usually) attacking the first in the list, but once that target dies and gets subtracted, the tower moves to the last target. The tower’s priority level is on First the entire time, but it acts as if it is on Last.

Here’s my code!

Also, if you guys have any suggestions on how to efficiently check if the first in the list isn’t necessarily the closest to the end zone, that would be a huge help.

void Update(){
UpdateTarget();
}

	public void UpdateTarget()
	{
		//If I don't have a target...
		if (myTarget != null) {
			//Get the distance between me and the target.
			if (Vector3.Distance (myTarget.gameObject.transform.position, this.transform.position) > maxAttackRange) {
				//If the target is too far away, set target to null.
				myTarget = null;
			} else {
				//Else, if my target is not in the target list...
				if (!eList.targetList.Contains (myTarget)) {
					//Set target to null
					myTarget = null;
				}
			}
			return;
		} else {
			//Else, if I DO have a target...
			switch(selectPriorityLevel){
				//If the priority level is set to first (Attack first enemy in the list...)
			case priority.first:
			//Iterate through the list and get the first available target in the list that is close enough to attack.
			for (int i = 0; i < eList.targetList.Count; i++) {
					//If the distance to the referenced target is within the maximum attack range..
				if (Vector3.Distance (eList.targetList *.transform.position, this.transform.position) < maxAttackRange) {*
  •  				//Set said target to MY target.*
    

_ myTarget = eList.targetList ;_
* //Rotate tower to follow enemy.*
* FollowEnemy ();*
* //If this is an AoE tower, exit function. Else, attack.*
* if (launchStyle == projectileLaunchStyle.aoe)return;*
* StartCoroutine (AttackEnemy ());*
* }*
* }*
* break;*
* case priority.last:*
* //If priority level is set to last (Attack last enemy in list…)*
* for (int i = 0; i < eList.targetList.Count; i++) {*
* //Iterate through the list and get the last available target in the list that is close enough to attack.*
* if (Vector3.Distance (eList.targetList[eList.targetList.Count-1].transform.position, this.transform.position) < maxAttackRange) {*
* myTarget = eList.targetList [eList.targetList.Count-1];*
* //Rotate tower to follow enemy.*
* FollowEnemy ();*
* //If this is an AoE tower, exit function. Else, attack.*
* if (launchStyle == projectileLaunchStyle.aoe)return;*
* StartCoroutine (AttackEnemy ());*
* }*
* }*
* break;*
* }*
* }*
* }*

In case priority.first: you don’t break out of the search loop if you find a target, so you end up going through the whole list and the last thing you do will be attacking the last item on the list that is within range, not the first one you find.

In the second one you loop eList.targetList.Count times but you compare distance to the last item on the list every time Vector3.Distance (eList.targetList [eList.targetList.Count - 1]....

Since you want to do the same thing in both cases, just in reverse order, you could do like this

public void UpdateTarget ()
	{
		if (myTarget != null)
		{
			if (Vector3.Distance (myTarget.gameObject.transform.position, this.transform.position) > maxAttackRange)
			{
				myTarget = null;
			}
			else
			{
				if (!eList.targetList.Contains (myTarget))
				{
					myTarget = null;
				}
			}
		// no need to have a return; here because there's no code after the if.
		// we entered the "if" so we won't enter the "else".
		//	return;
		}
		else
		{
			if (selectPriorityLevel == priority.first)
			{
				for (int i = 0; i < eList.targetList.Count; i++)
				{
					if (trySetAsTarget(eList.targetList*))*
  •  				return;*
    
  •  		}*
    
  •  	}*
    
  •  	else*
    
  •  	{*
    
  •  		for (int i = eList.targetList.Count-1; i >= 0; i--)*
    
  •  		{*
    

_ if (trySetAsTarget(eList.targetList*))_
_
return; // if target was found, stop searching*_
* }*
* }*
* }*
* }*

* // return whether a target was found or not*
* bool trySetAsTarget(MyTargetType target)*
* {*
* if (Vector3.Distance (target.transform.position, this.transform.position) < maxAttackRange)*
* {*
* //Set said target to MY target.*
* myTarget = target;*
* //Rotate tower to follow enemy.*
* FollowEnemy ();*
* //If this is an AoE tower, exit function. Else, attack.*
* if (launchStyle == projectileLaunchStyle.aoe)*
* return true;*
* StartCoroutine (AttackEnemy ());*

* return true; // target found and set*
* }*
* return false; // not close enough*
* }*