我正在制作我的第二款fps游戏。
我知道这个问题可能会重复,但我找不到任何解决问题的方法。因为我的剧本似乎一切都很好
所以,
我有一个场景,其中有一个空的游戏对象(spawnPoints(。它包含了所有繁殖敌人的产卵点。目的和问题我不想与敌人重叠。总共有6个产卵点。如果我把5作为产卵点的大小。一切都很好。。。也就是说,敌人不会重叠。但如果我把7、8或9作为spawnpoint数组的大小。敌人重叠。我使用Physics.overlapsphere来检测对撞机。
如果没有地方产卵,我不想产卵。如果没有地方产卵,那么我希望敌人等待。。。直到清除任何产卵点。
代码
using UnityEngine;
using System.Collections;
public class EnemySpawns :
MonoBehaviour {
public GameObject Enemy;
public Transform[] spawnPoints;
public float spawnTime;
public int maxEnemy = 5;
private int currentEnemy = 0;
bool isSpawn;
public float EnemyRadius = 16f;
void Start(){
isSpawn = false;
InvokeRepeating ("spawnEnemy", spawnTime, 5.4f);
isSpawn = true;
}
public void spawnEnemy(){
for (int i = 0; i < spawnPoints.Length; i++) {
Collider[] cols = Physics.OverlapSphere (spawnPoints [i].transform.position, EnemyRadius);
foreach (Collider hit in cols) {
if (hit.tag == "AI Controller")
{
isSpawn = false;
return;
}
else
{
isSpawn = true;
}
}
}
if (isSpawn == true) {
if (currentEnemy <= maxEnemy) {
Transform currentSpawnPoint = spawnPoints [Random.Range (0, spawnPoints.Length)].transform; //pickrandom
Instantiate (Enemy, currentSpawnPoint.position, currentSpawnPoint.rotation);
currentEnemy++;
}
}
if (currentEnemy == maxEnemy) { //stop spawning enemies
CancelInvoke ();
}}}
您的逻辑中有几个错误,我将您的代码重构为协程,因为我认为它更适合您的情况。
StartCoroutine(SpawnEnemies());
}
public IEnumerator SpawnEnemies()
{
while (_spawnedEnemies < _enemiesToSpawn.OrderBy(o => Random.value))
{
// You should really store these "magic numbers" in variables (5.4f)
yield return new WaitForSeconds(5.4f);
foreach (var spawnPoint in _spawnPoints)
{
var cols = Physics.OverlapSphere(spawnPoint.transform.position, EnemyRadius);
// I would recommend not using tags in general, instead maybe GetComponent<AIController>() or even better, use an enemy layer and use a mask when overlapping the sphere
if (cols.Any(c => c.tag == "AI Controller"))
{
continue;
}
Instantiate(_enemyPrefab, spawnPoint.position, spawnPoint.rotation);
currentEnemy++;
break;
}
}
}
基本上,该函数管理其生命周期,而不是使用invoke,它在所有生成点上迭代,检查是否有AI控制器,如果没有,则在那里生成敌人。
如果所有生成点都被占用,函数将等待定义的延迟(5.4s(,然后重试。
_enemiesToSpawn.OrderBy(o => Random.value)
是低性能点的快速洗牌(在您的情况下,它将每5.4秒被调用N次,这是可以忽略的(
你也可以在for循环后移动屈服点,这样你就可以毫不延迟地首先生成敌人,然后等待下一个生成。