在一组具有 3 个不同标签的敌人中找到最近的目标
Finding the closest target in a group of enemies with 3 different tags
我有一个双面游戏,炮塔需要找到最近的带有特定标签的目标。
LeftPlayer 有 3 个标签,用于 3 种不同的敌人类型。
RightPlayer 有 3 个标签,用于 3 种不同的敌人类型。
所以一共6个标签,每个玩家3个。
目前我正在使用 Udemy 的 RealmRush 课程中的 FindClosestTarget 方法,该方法几乎可以正常工作,但遗憾的是双方的炮塔都瞄准所有 6 种敌人类型。这就是为什么我试图找到一个使用标签的解决方案。
我可以举出前面提到的 Udemy RealmRush 方法的例子,它可能是可以挽救的,并且可以为每一方拆分成单独的脚本,但我不知道该怎么做。该脚本还包含我注释掉的使其基于标签的失败尝试。无论我在哪里寻找解决方案,我都只找到了一个标签的示例,该标签也无法正常工作。如果您认为可以比当前版本更容易保存,我非常乐意这样做。
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;
}
}
不完全清楚为什么要对所有类型的敌人使用不同的标签。使用继承或接口会更好,但是,根据您的要求 - 如果您想在方法中使用三个不同标签的搜索 - 然后在其中实现三个标签的搜索。
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;
}
我有一个双面游戏,炮塔需要找到最近的带有特定标签的目标。
LeftPlayer 有 3 个标签,用于 3 种不同的敌人类型。 RightPlayer 有 3 个标签,用于 3 种不同的敌人类型。 所以一共6个标签,每个玩家3个。
目前我正在使用 Udemy 的 RealmRush 课程中的 FindClosestTarget 方法,该方法几乎可以正常工作,但遗憾的是双方的炮塔都瞄准所有 6 种敌人类型。这就是为什么我试图找到一个使用标签的解决方案。
我可以举出前面提到的 Udemy RealmRush 方法的例子,它可能是可以挽救的,并且可以为每一方拆分成单独的脚本,但我不知道该怎么做。该脚本还包含我注释掉的使其基于标签的失败尝试。无论我在哪里寻找解决方案,我都只找到了一个标签的示例,该标签也无法正常工作。如果您认为可以比当前版本更容易保存,我非常乐意这样做。
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;
}
}
不完全清楚为什么要对所有类型的敌人使用不同的标签。使用继承或接口会更好,但是,根据您的要求 - 如果您想在方法中使用三个不同标签的搜索 - 然后在其中实现三个标签的搜索。
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;
}