Targeting system not holding a targert

I’m working on a 2d tower defense prototype and am having troubles getting a good targeting system. I’m pretty new to Unity and C#, but I managed to put together a system that finds and locks onto the closest target in range. But it’s acquiring new targets before the first target becomes null. I want it to hold that target until it is destroyed or goes out of range. Heres the code (forgive me for sloppy syntax)

public class InRange : MonoBehaviour {

public ShotScript redShot = null;	
public Transform playerStart;
public int speed;
public float range = 15f;

    
Reds findClosestTarget(){
	Reds closest = null;
	Vector3 pos = transform.position;

	//find all red
	Reds[] reds = (Reds[])FindObjectsOfType (typeof(Reds));
	if (reds != null){
		if (reds.Length > 0 ){
			closest = reds[0];
			for (int i = 1; i < reds.Length; ++i){
				float cur = Vector3.Distance(pos, reds*.transform.position);*
  •   			float old = Vector3.Distance(pos, closest.transform.position);*
    
  •   			if (cur < old) {*
    

_ closest = reds*;_
_
}_
_
}_
_
}_
_
}_
_
return closest;_
_
}*_

* // Update is called once per frame*
* void Update()*
* {*
* Reds target = findClosestTarget ();*
* if (target != null) {*
* if (Vector3.Distance (transform.position, target.transform.position) <= range){*

* //shoot bullets at target*
* GameObject g = (GameObject)Instantiate (redShot.gameObject, transform.position, Quaternion.identity);*
* ShotScript b = g.GetComponent ();*
* b.setDestination (target.transform);*
* }*
* }*
I tried Do While and While loops on the //shoot bullets; code block but that got me stuck and crashed Unity. My guess is it be a problem running these in Update() but I can’t figure out a solution. Any help is appreciated.

"I tried Do While and While loops on
the //shoot bullets; "

My good friend let me introduce you to Coroutines!

They let you do code over several frames, perfect for your logic issue.

example:

public ShotScript redShot = null;
public Transform playerStart;
public int speed;
public float range = 15f;

Reds findClosestTarget()
{
    Reds closest = null;
    Vector3 pos = transform.position;

    //find all red
    Reds[] reds = (Reds[])FindObjectsOfType(typeof(Reds));
    if (reds != null)
    {
        if (reds.Length > 0)
        {
            closest = reds[0];
            for (int i = 1; i < reds.Length; ++i)
            {
                float cur = Vector3.Distance(pos, reds*.transform.position);*

float old = Vector3.Distance(pos, closest.transform.position);
if (cur < old)
{
closest = reds*;*
}
}
}
}
return closest;
}
void Start()
{
//Start the coroutine
StartCoroutine(Shoot());
}
IEnumerator Shoot()
{
//Loop forever (just like update)
while (true)
{
//Get that target.
Reds target = findClosestTarget();
while (target != null)
{
//Shoot
if (Vector3.Distance(transform.position, target.transform.position) <= range)
{
//shoot bullets at target
GameObject g = (GameObject)Instantiate(redShot.gameObject, transform.position, Quaternion.identity);
ShotScript b = g.GetComponent();
b.setDestination(target.transform);
}

//wait for a frame
yield return null;
}
//Wait for a frame before looking again
yield return null;
}
}
If you still have some issues let me know and I will look at

@JanusMirith I got it. The problem was that co routines aren’t exclusive, so triggering it from update meant that I was triggering multiple coroutines at a time. I fixed it by setting a one time switch to start the co routine. It looks like this:

void Update()
	{
			//start coroutine
			if (begin) {
				
				StartCoroutine("Shoot");
				begin = false;
			}
	}

IEnumerator Shoot()
{
	//loop forevr, like Update()
	while (true) {
		//get target
		Reds target = findClosestTarget ();

		while (target != null) {
			//shoot
			if (Vector3.Distance (transform.position, target.transform.position) <= range) {
					isInRange = true;

					
					//shoot bullets at target
					GameObject g = (GameObject)Instantiate (redShot.gameObject, transform.position, Quaternion.identity);
					ShotScript b = g.GetComponent<ShotScript> ();
					b.setDestination (target.transform);
					
				}
				
				
			else 
			{       //target goes out of range or dies
				target = null;
			}

			yield return new WaitForSeconds(.1f);
		}
		//wait another frame before acquiring new target
		//yield return null;
		yield return null;
	}
}

thank you so much for pointing me there. I’ve learned a lot about them in this process. Hope this can help someone else.