TargetLocator... more efficient?

Hello, I have some aspirations of incorporating a Card Game mechanic, and larger levels into my build.
So, when Gary mentioned that the Target Locator could be more efficient, I decided to give it a try… here is my attempt… not sure if it actually is more efficient or not, but Its working well(not causing any errors, and I like the functionality it gives my towers) and I’m happy with it so far.

Edit: Swapped the Particle Effect for the projectile to a Beam, from the asset pack Polygon Arsenal, and added Randomized Damage for each time the beam connects, feels a lot better than it did.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PolygonArsenal;

public class TargetLocator : MonoBehaviour
{

    [SerializeField] Transform weapon; //Serialized for Debugging Purposes
    [SerializeField] Transform target; //Serialized for Debugging Purposes
    [SerializeField] float yOffset = 5f; //allows the Hieght of the projectile to be altered (so it doesnt shoot the ground);
    [SerializeField] PolygonBeamStatic projectileParticle; //the Particle System used for the Projectile
    [SerializeField] float range = 15f;
    [SerializeField] float targetDistance;
    [SerializeField] float firingDelay = 1f;
    [SerializeField] bool firing = false;

    [SerializeField] float minDamage = .1f;
    [SerializeField] float maxDamage = 5f;
    float damage;
    public float Damage { get => damage; }
    

    private void Awake()
    {
        weapon = transform.GetChild(1);//gets the Second transform child in the GameObject... this could be done with SerializeField,
                                       //or anyway method of getting the transfrom, for the towers weapon. its just initializing weapon.
        target = null;
        targetDistance = range + 1;
        
    }
   
    void Update()
    {
        if (target != null)
        {
            AimWeapon();
            if (!target.gameObject.activeInHierarchy) //checks if the current target is still viable
            {
                FindClosestTarget();
               
            }
            CheckRange();
        }
        if (target == null) //Mainly for initialization purposes, but if for some reason the Target becomes null, deactivates the towers firing, and 
                            // targets the closest enemy.
        {
            projectileParticle.RemoveBeam();
            FindClosestTarget();
        }
       
    }

    /// <summary>
    /// Aims the weapon transform at the current target, if no target looks at (0, yOffset ,0)
    /// </summary>
    void AimWeapon()
    {
        if (target != null)
        {
            targetDistance = Vector3.Distance(transform.position, target.position);
            weapon.LookAt(new Vector3(target.position.x, target.position.y + yOffset, target.position.z));
            
        }
        else
        { weapon.LookAt(new Vector3(0, yOffset, 0)); }
    }

    private void CheckRange()
    {
        if (targetDistance > range)
        { projectileParticle.RemoveBeam();
            FindClosestTarget();
        }
        else if (targetDistance < range)
        {
            if (!firing)
            {
                StartCoroutine(Fire());
            }
        }
    }
    void SetDamage()
    {
        damage = UnityEngine.Random.Range(minDamage, maxDamage);
        print($"Damage = {damage}");
    }
    IEnumerator Fire()
    {
        SetDamage();
        projectileParticle.SpawnBeam();
        firing = true;
        yield return new WaitForSeconds(firingDelay/2);
        projectileParticle.RemoveBeam();
        yield return new WaitForSeconds(firingDelay/2);
        firing = false;
    }

    /// <summary>
    /// Calls FindClosestTarget, and starts the particle system.
    /// </summary>
    private void GetTarget()
    {
        FindClosestTarget();       
    }

    /// <summary>
    /// Locates all enemies in the scene, determines which is closest to the Tower, and sets the target to that enemy
    /// </summary>
    void FindClosestTarget()
    {
        
        Enemy[] enemies = FindObjectsOfType<Enemy>();
        Transform closestTarget = null;
        float MaxDistances = Mathf.Infinity;

        foreach (Enemy enemy in enemies)
        {
            float targetDistance = Vector3.Distance(transform.position, enemy.transform.position);
            if (targetDistance < MaxDistances)
            {
                closestTarget = enemy.transform;
                MaxDistances = targetDistance;
            }
        }

        target = closestTarget;

        if (target != null)
        {
            Fire();
        }

    }
}

}```
3 Likes

Here is a video of my Build so far… I am especially proud of my custom Orbit camera… It took 3 days to build, but I’m SUPER happy with it!

1 Like

Updated Video

2 Likes

Privacy & Terms