I have a two-sided game, where turrets need to find the closest targets with specific tags.
LeftPlayer has 3 tags for 3 different enemy types. RightPlayer has 3 tags for 3 different enemy types. So a total of 6 tags, 3 for each Player.
Currently I'm using the FindClosestTarget method from Udemy's RealmRush course, which works almost right, but sadly both side's turrets target all 6 enemy types. That is why I'm trying to find a solution that uses tags.
I can give example of the forementioned Udemy RealmRush method, which might be salvagable and split into separate scripts for each side, but I don't know how to do so. The script also contains my commented out failed attempt at making it tag-based. Wherever I looked for solutions, I've only found examples for one tag, which also refuses to work. If you think that can be saved easier than the current version, I'm more than happy to do just that.
using Vector3 = UnityEngine.Vector3;
public class TargetLocator : MonoBehaviour
{
[SerializeField] Transform weapon;
[SerializeField] ParticleSystem projectileParticles;
[SerializeField] float range = 1.5f;
[SerializeField] Transform enemy;
//public GameObject Target;
public float maxDistance;
void Update()
{
/*Target = FindClosestEnemy();
range = Vector3.Distance(transform.position, Target.transform.position);
if (maxDistance < range)
{
FindClosestEnemy();
}*/
FindClosestTarget();
AimWeapon();
}
/*public GameObject FindClosestEnemy()
{
Enemy[] enemies;
enemies = GameObject.FindGameObjectsWithTag("LeftBrute");
GameObject closest;
float maxDistance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (Enemy enemy in enemies)
{
Vector3 diff = enemy.transform.position - position;
float currentDistance = diff.sqrMagnitude;
if (currentDistance < maxDistance)
{
closest = Target;
maxDistance = currentDistance;
}
}
return Target;
}*/
void FindClosestTarget()
{
Enemy[] enemies = FindObjectsOfType<Enemy>();
Transform closestTarget = null;
float maxDistance = Mathf.Infinity;
foreach (Enemy enemy in enemies)
{
float targetDistance = Vector3.Distance(transform.position, enemy.transform.position);
if (targetDistance < maxDistance)
{
closestTarget = enemy.transform;
maxDistance = targetDistance;
}
}
enemy = closestTarget;
}
public void AimWeapon()
{
float maxDistance = Vector3.Distance(transform.position, enemy.transform.position);
if (maxDistance < range)
{
weapon.LookAt(enemy.transform.position);
Attack(true);
}
else
{
Attack(false);
Debug.Log("Target not found");
}
}
public void Attack(bool isActive)
{
var emissionModule = projectileParticles.emission;
emissionModule.enabled = isActive;
}
}
it is not entirely clear why different tags should be used for all types of enemies. It would be better to use inheritance or interfaces, but, according to your request - if you want to use a search by three different tags in the method - then implement a search by three tags in it.
public void FindClosestEnemy()
{
List<GameObject> nearestEnemies = new List<GameObject>();
GameObject lastAddedEnemy = null;
GameObject enemyTemp = null;
float maxDistance = Mathf.Infinity;
Vector3 position = transform.position;
enemyTemp = FindNearestWithTag("LeftBrute_1"); // your tag name
if (enemyTemp != null && enemyTemp != lastAddedEnemy)
{
nearestEnemies.Add(enemyTemp);
lastAddedEnemy = enemyTemp;
}
enemyTemp = FindNearestWithTag("LeftBrute_2"); // your tag name
if (enemyTemp != null && enemyTemp != lastAddedEnemy)
{
nearestEnemies.Add(enemyTemp);
lastAddedEnemy = enemyTemp;
}
enemyTemp = FindNearestWithTag("LeftBrute_3"); // your tag name
if (enemyTemp != null && enemyTemp != lastAddedEnemy)
{
nearestEnemies.Add(enemyTemp);
lastAddedEnemy = enemyTemp;
}
foreach (var enemy in nearestEnemies)
{
Vector3 diff = enemy.transform.position - position;
float currentDistance = diff.sqrMagnitude;
if (currentDistance < maxDistance)
{
enemyTemp = enemy;
maxDistance = currentDistance;
}
}
Target = enemyTemp;
}
private GameObject FindNearestWithTag(string tagName)
{
GameObject[] enemies;
enemies = GameObject.FindGameObjectsWithTag(tagName);
GameObject closest = null;
float maxDistance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (var enemy in enemies)
{
Vector3 diff = enemy.transform.position - position;
float currentDistance = diff.sqrMagnitude;
if (currentDistance < maxDistance)
{
closest = enemy;
maxDistance = currentDistance;
}
}
return closest;
}