Hi I am making a Chain Lightning spell that needs to bounce from one unit to the nearest, and so on, never hitting the same unit twice. I have done it using the code below. The issue I have is that the only way I could get it to work (im not experienced with lists) is to change the units tag when hit, and then run the find nearest unit again. However that will cause issues for other parts of my game, so I am looking to make a list that doesn’t just find the nearest unit, but also the next nearest unit and so on.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChainLightningBounce : MonoBehaviour
{
GameObject targetObject;
Vector2 moveSpot;
public float speed;
public float bounceNumber;
public float damage;
public List<GameObject> targetsToAttack;
TakeDamage takeDamageScript;
public bool findTarget;
bool triggered;
AudioSource audioEffect;
void Start()
{
StartCoroutine(nameof(WaitGoTarget));
GetClosestObjectDamage();
audioEffect = GameObject.Find("Chain Lightning Audio").GetComponent<AudioSource>();
}
IEnumerator WaitGoTarget()
{
yield return new WaitForSeconds(0.15f);
findTarget = true;
audioEffect.Play();
}
void Update()
{
if(findTarget == false)
{
return;
}
transform.position = Vector2.MoveTowards(transform.position, targetObject.transform.position,
speed * Time.deltaTime);
// rotate object in direction it is travelling //
Vector2 dir = targetObject.transform.position - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
//----------------------------------------------//
if (transform.position == targetObject.transform.position && bounceNumber > 0 && targetsToAttack.Count > 0)
{
if(triggered == false)
{
triggered = true;
AttackingEnemyDamage();
}
}
if(bounceNumber <= 0 || targetsToAttack.Count == 0)
{
Destroy(gameObject);
}
}
public GameObject GetClosestObjectDamage()
{
targetsToAttack = new List<GameObject>();
targetsToAttack.AddRange(GameObject.FindGameObjectsWithTag("EnemyUnits"));
float closest = 1000; //add your max range here
GameObject closestObject = null;
for (int i = 0; i < targetsToAttack.Count; i++) //list of gameObjects to search through
{
float dist = Vector3.Distance(targetsToAttack[i].transform.position, transform.position);
if (dist < closest)
{
closest = dist;
closestObject = targetsToAttack[i];
}
}
if (targetsToAttack.Count != 0)
{
moveSpot = closestObject.transform.position;
targetObject = closestObject;
}
return closestObject;
}
public void AttackingEnemyDamage()
{
takeDamageScript = targetObject.GetComponent<TakeDamage>();
if (takeDamageScript.currentHealth > damage)
{
bounceNumber -= 1;
}
takeDamageScript.NPCTakeDamageChainSpell(damage);
StartCoroutine(nameof(WaitNextZap));
}
IEnumerator WaitNextZap()
{
yield return new WaitForSeconds(0.1f);
GetClosestObjectDamage();
triggered = false;
}
}