提问人:Kurt Roberts 提问时间:11/17/2023 更新时间:11/18/2023 访问量:49
Unity 中是否有 C# 函数来检测设定范围内的某种类型的游戏对象?
Is there a C# function in unity to detect a certain type of gameObject within a set range?
问:
我正在编写一个生存游戏,我希望敌人在特定范围内(例如 10m)内瞄准最近的玩家。有没有检测最近的玩家的功能,以便我可以对攻击和动作进行编程?
我尝试分配玩家并使用简单的 GameObject.LookAt 进行操作,但这不允许针对多个玩家,我只希望玩家在一定范围内成为目标。
答:
0赞
Priyansh Yadav
11/18/2023
#1
这很容易。您也可以按照 @BugFinder 的评论中的建议使用球体投射来实现它。但是,我建议使用简单的 GameObject.Find 方法。
首先,您应该制作一个玩家单行为并将其附加到所有玩家。
public class PlayerMono : MonoBehaviour
{
// Implement you player code here
}
然后,在敌人的单一行为中 - 要找到最近的玩家,请添加以下代码。
public class EnemyMono : MonoBehaviour
{
// Your custom code here...
private PlayerMono[] allPlayers; // This list should be cached bcz it has a little bit of overhead which makes it non-feasible to be called everytime.
private PlayerMono GetNearestPlayer(Vector3 enemyPosition)
{
if (allPlayers == null)
{
allPlayers = GameObject.FindObjectsOfType<PlayerMono>();
// otherwise do the following if you dont have a PlayerComponent and change PlayerMono references with GameObject
// allPlayers = GameObject.FindGameObjectWithTag("PlayerTag");
}
// Make sure to not cache the following array as it will not take into account the updated positions of the Player.
Vector3[] allPlayersPositions = allPlayers.Select(player => player.transform.position).ToArray();
PlayerMono nearestPlayer = allPlayers[GetNearestPlayerIndex(transform.position, allPlayersPositions)];
return nearestPlayer;
}
// You need to install the Burst Package for this. If it confuses you,
// simply comment the [BurstCompile]. It won't have any effect on the result of the code.
// I just tend to do this as a habit for such functions where i am looping over vectors or other such types.
[BurstCompile]
private int GetNearestPlayerIndex(Vector3 enemyPosition, Vector3[] allPlayersPositions)
{
Vector3 nearestPosition = Vector3.positiveInfinity;
int nearestPlayerIndex = 0;
int currentIndex = 0;
foreach (var playerPosition in allPlayersPositions)
{
if (Vector3.Distance(enemyPosition, playerPosition) < nearestPosition.magnitude)
{
nearestPosition = playerPosition;
nearestPlayerIndex = currentIndex;
}
currentIndex++;
}
return nearestPlayerIndex;
}
}
现在你可以对最近的玩家做任何你想做的事情,比如:
PlayerMono nearestPlayer = GetNearestPlayer();
if (Vector3.Distance(transform.position, nearestPlayer.transform.position) <= 10f)
{
AttackPlayer(nearestPlayer); // implement it according to your needs.
}
else
{
JustRelax(); // Exhibit Idle behaviour
}
评论
0赞
derHugo
11/19/2023
如果已经在使用 Linq,您可以继续使用FindObjectsOfType<PlayerMono>().OrderBy(o => (transform.position - o.tranaform.position).sqrMagnitude).FirstOrDefault();
评论