
在本教程中,将学习如何在Unity中找到最近的敌人,寻找最近的敌人或物体也是开发游戏的常见需求之一,本文将会使用以下方法来计算最近的敌人。
遍历敌人列表
当Unity软件中没有很多敌人时,此方法很有用,使用下面的脚本在Unity中找到最近的敌人或物体。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClosestEnemyBehaviour : MonoBehaviour
{
public Transform Player;
public List<Transform> EnemyList;
private Transform nearestEnemy;
void Update()
{
float minimumDistance = Mathf.Infinity;
if(nearestEnemy!=null)
{
nearestEnemy.GetComponent<MeshRenderer>().material.color = Color.green;
}
nearestEnemy = null;
foreach(Transform enemy in EnemyList)
{
float distance = Vector3.Distance(Player.position, enemy.position);
if ( distance < minimumDistance)
{
minimumDistance = distance;
nearestEnemy = enemy;
}
}
nearestEnemy.GetComponent<MeshRenderer>().material.color = Color.red;
Debug.Log("Nearest Enemy: " + nearestEnemy + "; Distance: " + minimumDistance);
}
}
KD树
如果敌人列表很大或者想要获得多组对象之间的最小距离,那么上述方法将花费更多的时间来计算并且会导致低FPS。
KDTree数据结构帮助我们非常快速地进行这些计算(可以从这里参阅),因为它将数据存储在K维空间中,使用KDTree查找最近的对象将提高性能。
可以在互联网上找到许多关于Unity的KDTre算法的脚本,下面三个是几个例子,本文使用了第一个。
- https://github.com/orifmilod/KdTree-Unity3D
- https://github.com/viliwonka/KDTree
- https://gist.github.com/ditzel/194ec800053ce7083b73faa1be9101b0
下面给出了使用KdTree的示例脚本,可以在这里获取脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClosestEnemyKdTree : MonoBehaviour
{
public Transform Player;
//First add your enemy transform in C# List
public List<Transform> EnemyList;
private KdTree<Transform> enemyKdTree = new KdTree<Transform>();
private Transform nearestEnemy;
void Start()
{
// Update EnemyKdTree
enemyKdTree.AddAll(EnemyList);
}
void Update()
{
if (nearestEnemy != null)
{
nearestEnemy.GetComponent<MeshRenderer>().material.color = Color.green;
}
// get closest object
nearestEnemy = enemyKdTree.FindClosest(Player.position);
nearestEnemy.GetComponent<MeshRenderer>().material.color = Color.red;
float distance = Vector3.Distance(Player.position, nearestEnemy.position);
Debug.Log("Nearest Enemy: " + nearestEnemy + "; Distance: " + distance);
}
}
物理领域重叠
还可以使用物理OverlapSphere方法来优化最近的敌人计算,这将提供球体半径内的敌人集合,球体中心将是玩家位置,只会在那个球体内找到最近的敌人。
下面的脚本将允许使用物理球体重叠方法获得最近的敌人,一个层被分配给所有敌人对象,所以它只会返回敌人对象。
要了解有关图层蒙版的更多信息,可以查看站内文章:
using System.Collections;
using UnityEngine;
public class ClosestEnemyColliderOverlap : MonoBehaviour
{
public Transform Player;
public float OverlapRadius = 10.0f;
private Transform nearestEnemy;
private int enemyLayer;
private void Start()
{
enemyLayer = LayerMask.NameToLayer("Enemy");
Debug.Log(enemyLayer);
}
void Update()
{
if(nearestEnemy!=null)
{
nearestEnemy.GetComponent<MeshRenderer>().material.color = Color.green;
}
Collider[] hitColliders = Physics.OverlapSphere(Player.position, OverlapRadius, 1 << enemyLayer);
float minimumDistance = Mathf.Infinity;
foreach(Collider collider in hitColliders)
{
float distance = Vector3.Distance(Player.position, collider.transform.position);
if (distance < minimumDistance)
{
minimumDistance = distance;
nearestEnemy = collider.transform;
}
}
if(nearestEnemy!=null)
{
nearestEnemy.GetComponent<MeshRenderer>().material.color = Color.red;
Debug.Log("Nearest Enemy: " + nearestEnemy + "; Distance: " + minimumDistance);
}
else
{
Debug.Log("There is no enemy in the given radius");
}
}
}
输出情况:
移动胶囊玩家之后,最近的敌人(方块)会变成红色。

…
以上是3D天堂网关于在Unity中寻找最近的敌人的全部内容,如果你有任何反馈,请随时在本页面下方留言。
学习如何在Unity中找到最近的敌人