2016-02-25 5 views
0

Мне нужно знать число enemyCans влево, поэтому, когда нет оставшихся, я могу вызвать условие выигрыша. Прямо сейчас у меня есть сценарий на моем компоненте взрыва, который функционирует правильно, что означает, что он удаляет любую пушку врагов, которая находится на определенном расстоянии от взрыва.
enemyCans объявляется и присваивается следующее значение в методе start(), соответственно:Проверка количества объектов GameObject в моем массиве

GameObject[] enemyCans; //Before start 
void Start() { 
enemyCans = GameObject.FindGameObjectsWithTag("EnemyCannon"); 
} 

Затем я использую это значение в методе, называемом CannonKiller(), который перебирает Превращает противника Кэннона, чтобы проверить и посмотреть, если приходит взрыв рядом с ними. Я уверен, что это не самый элегантный способ сделать это, но aforemention метод приведен ниже:

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

, но я был некорректен. Как я могу проверить, нет ли у них оставшихся вражеских пушек, чтобы вызвать мой метод финиша.

+1

cant вы проверяете, '' Array.Length == 0'? – Jacobr365

+0

Вы можете подсчитать количество уничтоженных пушек и сравнить их с врагомCans.Length – Casperah

+1

HI Austin, чтобы быть понятным, вы имеете в виду, что вы ** не знаете, какой вызов должен получить длина массива или List **? Вы можете объяснить? это просто длина, как упоминает Джейкоб – Fattie

ответ

1

Если это возможно, я предложил бы избежать необходимости слишком много вложенных foreach петель, как что, хотя ответ Джерри действительно работает, в худшем случае у вас будет, в основном, алгоритм сложности O (n), и его немного сложно прочитать.

Если у вас есть коллайдеры на всех ваших башнях, тогда вы должны использовать физический движок. Цель вашего кода будет, по крайней мере, намного яснее, если вы используете метод, подобный 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 , Я использовал его для «всех уничтоженных» чек.

Возможно, это не самый лучший подход, но я думаю, что он так же хорош, как и без существенного изменения вашей реализации. (Наличие класса менеджера, предложенного Джо, - это хороший способ разделить обязанности между классами и сделать ваш код более подверженным тестированию/поддерживаемому), поэтому обязательно посмотрите на это, так как он будет значительно увеличиваться по мере роста вашего проекта.)

+1

Я действительно думаю, что стоит подумать, что подход OP - * неверно ошибочный *.Скажем, я вел грузовик с ядерными отходами, которые я вложил в картонные контейнеры, которые горели, а также грузовик был в огне, а также я просто разбился в детском доме, и я спросил: «Какой лучший способ пополнить жидкость стеклоочистителя ветрового стекла ". Как будто. – Fattie

+0

в состоянии 'enemyCans.FirstOrDefault..', как бы вы правильно определяли' cannon' в настоящее время каждый раз, когда ударяется пушка, он запускает мой метод win –

+0

@AustinMauldin. Моя ошибка! Он должен проверять равенство, а не неравенство на «null» в этой строке. Исправлена ​​опечатка, дайте мне знать, если у вас есть другие вопросы. – Serlite

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

Но я должен сказать, что это очень некрасиво способ программирования;)

+0

Jez - Я думаю, что вы и я примерно одинаково озадачены этим вопросом! :) – Fattie

Смежные вопросы