我需要知道剩下的enemyCans
的数量,所以当没有剩余时,我可以触发我的胜利条件。现在,我的爆炸组件上有一个脚本,它可以正常运行,这意味着它可以移除任何爆炸范围内的敌人加农炮。
声明enemyCans
并在start()
方法中为其分配以下值:
GameObject[] enemyCans; //Before start
void Start() {
enemyCans = GameObject.FindGameObjectsWithTag("EnemyCannon");
}
然后,我在名为CannonKiller()
的方法中使用该值,该方法遍历Enemy Cannon的变换以检查爆炸是否接近它们。我确信这不是最优雅的方式,但上面列出的方法如下:
void CannonKiller()
{
foreach(var cannon in GameObject.FindGameObjectsWithTag("EnemyCannon").Select(enemyCans => enemyCans.transform).ToArray())
{
foreach (var aCan in enemyCans)
{
float enemyDis = Vector3.Distance(cannon.position, transform.position);
if (enemyDis <= 4)
{
Destroy(aCan);
}
}
}
}
我希望能够检查并查看嵌套的foreach
循环,看看敌人的数量是否为零所以我可以调用我的终结方法。我认为这样的事情会起作用:
if (enemyCans == 0) //placed inside the foreach
{
finish("enemy");
}
但我错了。我如何检查他们是否没有剩下的敌人大炮,以便调用我的完成方法。
答案 0 :(得分:1)
嗯,这段代码可行:
void CannonKiller()
{
foreach(var cannon in GameObject.FindGameObjectsWithTag("EnemyCannon").Select(enemyCans => enemyCans.transform).ToArray())
{
foreach (var aCan in enemyCans)
{
float enemyDis = Vector3.Distance(cannon.position, transform.position);
if (enemyDis <= 4)
{
Destroy(aCan);
bool allDestoyed = true;
foreach (GameObject o in enemyCans)
{
if (o != null && o != aCan)
{
allDestoyed = false;
break;
}
}
if (allDestoyed)
{
// Here you know all are destroyed
}
}
}
}
}
但我必须说这是一种非常丑陋的编程方式;)
答案 1 :(得分:1)
如果可能的话,我建议避免使用那么多嵌套foreach
循环 - 虽然Jerry的答案确实有效,但在最坏的情况下你基本上会有一个O(n 3 )复杂度算法,它有点难以阅读。
如果你的所有炮塔上都有碰撞器,那么你应该利用物理引擎。如果你使用像Physics.OverlapSphere
这样的方法识别爆炸所袭击的炮塔,你的代码的意图至少会更加清晰。
因此调整CannonKiller()
以摧毁命中炮塔并确定它们是否全部被摧毁(但以可以说是更整洁的方式),您的方法可能如下所示:
void CannonKiller()
{
// Grab colliders in vicinity of explosion
Collider[] hitColliders = Physics.OverlapSphere(transform.position, 4);
foreach (Collider hitCollider in hitColliders){
// Only act if collider belongs to an enemy cannon
if (hitCollider.gameObject.tag == "EnemyCannon"){
Destroy(hitCollider.gameObject);
// If there are no non-null references to cannon objects, they're all destroyed
if (enemyCans.FirstOrDefault(cannon => cannon != null) == null){
// Execute finishing code, then probably break
}
}
}
}
因为我看到你已经熟悉了LINQ,所以我将它用于&#34;所有被破坏的&#34;检查。
这可能不是最好的方法,但我认为它不会在不严重改变您的实施的情况下获得。 (像Joe建议的那样拥有一个管理器类是一种在类之间分配职责,并使代码更易于测试/维护的好方法 - 因此请务必深入研究,因为随着项目的增长,它会扩展得更好。)