【问题标题】:Physics.Overlapsphere isn't detecting collidersPhysics.Overlapsphere 没有检测到对撞机
【发布时间】:2020-07-21 00:23:39
【问题描述】:

我正在开发我的第二个 fps 游戏。

我知道这个问题可能会重复,但我找不到任何解决方法。 因为在我的脚本中似乎一切都很好。

所以,

我有一个场景,其中我有一个空的游戏对象(spawnPoints)。它包含生成敌人的所有生成点。 目的和问题 我不想让敌人重叠。共有6个出生点。如果我把 5 作为生成点的大小。一切正常......即,敌人不会重叠。但是如果我将 7、8 或 9 作为生成点数组的大小。敌人重叠。我正在使用 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 ();
     }}} 

【问题讨论】:

  • 对不起我的英语,但是“重叠”是指敌人不会停止产卵?
  • 你确定标签“AI控制器”与生成的敌人有关联吗?
  • AI Controller 标签链接到敌人。重叠意味着,敌人在同一个生成点被实例化 3-4 次。你的英语很好。

标签: unity3d physics overlap spawn collider


【解决方案1】:

你的逻辑有几个错误,我将你的代码重构为协程,因为我认为它更适合你的情况。

            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;
                }
            }
        } 

基本上,该函数管理它的生命周期与使用调用,它迭代所有生成点,检查是否有任何 AI 控制器,如果没有,则在那里生成一个敌人。

如果所有生成点都被占用,该函数将等待定义的延迟(5.4 秒)然后重试。

_enemiesToSpawn.OrderBy(o =&gt; Random.value) 是低性能点的快速洗牌(在您的情况下,这将每 5.4 秒调用 N 次,可以忽略不计)

你也可以在 for 循环之后移动 yielding,这样你会首先毫无延迟地生成一个敌人,然后才等待下一次生成。

【讨论】:

  • 我应该在哪里使用 Transform currentSpawnpoint? _spawn 点是什么?我没有用它作为标识符。我是。迷茫!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 2019-12-07
  • 1970-01-01
相关资源
最近更新 更多