Targetting enemy, repeating code

Hi all,

So my issue is i have produced messy code. I have a gun and a bullet. In a fixedupdate in the gun, it searches through all the spawned enemies and stored the closest in a variable called myTarget. Then when the player presses a ui element, a bullet is instantiated. Ideally in the start() of the instantiated bullet object i have something like enemy = player.GetComponent().GetTarget(); Which should return the myTarget. However no matter what i tried various things would happen, a bullet would spawn with no target even though one is passed. So now ive created that same loop through all the enemies to search for the target again, it might not even be the same as the myTarget in the gun now!

    public GameObject NearestEnemy() {

        enemies = GameObject.FindGameObjectsWithTag("Enemy");
        myTarget = null;
        float distance = Mathf.Infinity;
        Vector3 position = transform.position;
        foreach (GameObject enemy in enemies){
            Vector3 diff = enemy.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance){
                    myTarget = enemy;
                    distance = curDistance;
            }
            if (myTarget == enemy){
                //Debug.Log("My closest selected enemy so far is: " + myTarget.transform.name);
            }
        }
            return myTarget;
        }
    

    public void LazerAttack(){
        if (myTarget == null){

        } else if (Vector3.Distance(myTarget.transform.position, transform.position) < range && ammo > 0 && !bulletSpawned && myTarget != null){// if myTarget is in range then fire AND bullet spawned false
            //Debug.Log(" target is " + myTarget);
            bulletSpawned = true;
            //Debug.Log("set bullet spawned to " + bulletSpawned);
            Instantiate(bulletPrefab, transform.position, transform.rotation); // spawn bullet at the players current pos
      
            ammo--;
        }
        //Debug.Log ("ATTACK BUTTON PRESSED");
    }

So i have it working with essentially the same script which loops through all the enemies and returns the closest. Which is messy and not good. Anyone know how i can pass the myTarget to the instantiated bullet. In the fixedupdate of the buller i have a slerp which follows the nearest enemy.

Ive tried creating a setter in the bullet but no luck, it just fires into space. Ive also tried a getter in the bullet to the gun to get the target with no luck either!
Thanks for the help

after spawning the bullet get the bullet’s script and simply pass in the value.

    public float range;
    public int ammo;
    public GameObject bulletPrefab;
    
    private GameObject myTarget;
    private float targetRange;
    
    public void LazerAttack()
    {
        GetNearestEnemy();
        
        if(myTarget  &&  ammo>0  &&  targetRange  <  range)
        {
            GameObject bullet = GameObject.Instantiate<GameObject>(bulletPrefab);
            bullet.transform.position = transform.position;
            bullet.transform.rotation = Quaternion.identity;

            //you need to get the bullet's monobehaviour to set its target after instantiating
            BulletScript script = bullet.GetComponent<BulletScript>();
            script.target = myTarget;
            
            --ammo;
        }
    }
    
    
    void GetNearestEnemy()
    {
        myTarget = null;
        targetRange = 0;
        
        //We don't need to use FindGameObjectWithTag!
        //enemies = GameObject.FindGameObjectsWithTag("Enemy");
        
        //This is much faster!
        foreach ( GameObject enemy in EnemyScript.Enemies)
        {
            float currDistance  = (enemy.transform.position -  transform.position).magnitude;
            
            if(!myTarget || currDistance<targetRange )
            {
                myTarget = enemy;
                targetRange  = currDistance;
            }
        }
    }

With BulletScript being the actual monobehavior you have on your bullet (do note that the bullet script won’t have access to the myTarget variable in the Awake(), since that runs immeadiately when you instantiate the bullet prefab).

Also FindGameObjectsWithTags is a pretty slow function (and performance might be a factor depending on how many times you call LazorAttack() each second). instead if you just slightly prep your enemy’s monobehavior script you can possibly get a noticeable increase in framerate.

using System.Collections.Generic;

public class EnemyScript : MonoBehaviour
{
    private static List<GameObject> enemies = new List<GameObject>();
    
    public static List<GameObject> Enemies
    {
        get
        {
            return new List<GameObject>(enemies);
        }
    }
    
    void OnEnable()
    {
        enemies.Add(gameObject);
    }
    
    void OnDisable()
    {
        enemies.Remove(gameObject);
    }
}