Почему случай с моим переключателем должен быть правильным, а выход-нет?

#c# #unity3d #switch-statement

Вопрос:

У меня есть способность на моем игроке, которая выделяет врагов на короткое время, для этого все хорошо работает. Я решил сделать это обновляемым, чтобы чем выше уровень способности, тем больше материала выделяется.

  • Враги 0-го уровня (базовый уровень) подсвечиваются.
  • Враги и предметы 1-го уровня подсвечиваются.
  • Враги 2-го уровня, предметы и специальные предметы выделяются.
  • Враги 3-го уровня, предметы, специальные предметы и скрытые области выделяются.

Для этого я подумал, что переключатель, работающий в IEnumerator (сопрограмме), будет наиболее эффективным способом. Функция вызывает сопрограмму, и в зависимости от уровня, который игрок имеет для способности, переключатель должен обрабатывать фактическую функциональность способности (см. Код).

Вот код:

 public void CatsEye(){  if (player.cateye gt;= 1 amp;amp; !catsEyeActive) {   player.cateye -= 1;  StartCoroutine("CatEye");  // Debug.Log("Cateye Active");   } }   IEnumerator CatEye(){  catsEyeActive = true;   switch(player.cateyeLevel){  case 3:  if (itemObject != null amp;amp; enemyObject != null  amp;amp; specialObject != null amp;amp; hiddenObject != null) {  hidden.isOutlined = true;  special.isOutlined = true;  enemyData.isOutlined = true;  item.isOutlined = true;  }  yield return new WaitForSeconds(15f);  if (itemObject != null amp;amp; enemyObject != null) {  hidden.isOutlined = false;  special.isOutlined = false;  enemyData.isOutlined = false;  item.isOutlined = false;  }  catsEyeActive = false;  break;    case 2:  if (itemObject != null amp;amp; enemyObject != null amp;amp; specialObject != null) {  special.isOutlined = true;  enemyData.isOutlined = true;  item.isOutlined = true;  }  yield return new WaitForSeconds(15f);  if (itemObject != null amp;amp; enemyObject != null) {  special.isOutlined = false;  enemyData.isOutlined = false;  item.isOutlined = false;  }  catsEyeActive = false;  break;    case 1:  if (itemObject != null amp;amp; enemyObject != null) {  enemyData.isOutlined = true;  item.isOutlined = true;  }  yield return new WaitForSeconds(15f);  if (itemObject != null amp;amp; enemyObject != null) {  enemyData.isOutlined = false;  item.isOutlined = false;  }  catsEyeActive = false;  break;    case 0:  if (enemyObject != null) {  enemyData.isOutlined = true;  }  yield return new WaitForSeconds(15f);  if (enemyObject != null) {  enemyData.isOutlined = false;  }  catsEyeActive = false;  break;  } }  

Проблема в том, что даже при player.cateyeLevel значении 0 способность действует так, как будто она находится на уровне 3 и выделяет все.

Это player.cateyeLevel относится к сценарию игрока, но там нет установленных переменных, которые могли бы быть причиной проблемы. На самом деле, во всяком случае, player.cateyeLevel переменная для этой способности была установлена в 0. Там также нет PlayerPrefs хранения player.cateyeLevel , так что это тоже не так.

У кого-нибудь есть идея?

Комментарии:

1. В сопрограмме нет ничего плохого, хотя я бы вызвал функцию напрямую как StartCoroutine(CatEye());. Поставьте отладку. Журнал(игрок.cateyeLevel. toString()) вызовите непосредственно перед оператором switch, чтобы проверить вашу логику. Если он печатает «0», как вы ожидаете, должен быть какой-то другой скрипт, изменяющий свойства isOutline. Затем выполните дополнительные вызовы Debug.Log() или используйте отладчик.

2. @AndulfGames-AndersBjerin Попробовал ваше предложение, но возникает та же проблема 🙁 в файле outline.cs нет ничего, что могло бы вызвать проблему, так как все, что он делает, — это включает или отключает эффект шейдера на игровом объекте, если пул isOutlined верен. нет подключения к плееру.переменная cateyeLevel. Хотя спасибо за предложение

3. Странно, но в этом случае я бы добавил точку останова в первой строке функции CatEye() и вручную включил отладчик, чтобы проверить, что происходит. Альтернативой также является добавление большого количества временных вызовов Debug.Log ()… счастливой охоты.

4. @Twisted Я просто комментировал — в том, что ты сделал, на самом деле нет ничего плохого. Мне нравится, как вы написали это ниже — это выглядит намного чище. Я просто говорил, что письмо if (x amp;amp; y) {z = true;} иногда может быть легче читать, как z = (x amp;amp; y); . Когда у вас есть switch случаи, в которых задается набор одних и тех же переменных на основе значения, его часто можно свести к более простым операторам set. Кодирование — это такое же искусство, как и наука, и единственным реальным показателем успеха является рабочий код, отвечающий его требованиям.

5. @Twisted Например, первым foreach в приведенном ниже коде может быть: foreach (игровой объект enemyObject в enemyObjects) { enemyData = enemyObject.GetComponentlt;Врагgt;(); если (enemyObject != null) { enemyData.isOutlined = (catsEyeActive amp;amp; player.cateyeLevel == 0); } }

Ответ №1:

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

 void Update()  {   enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");  foreach(GameObject enemyObject in enemyObjects){  enemyData = enemyObject.GetComponentlt;Enemygt;();  if (enemyObject != null) {  if (catsEyeActive amp;amp; player.cateyeLevel == 0) {  enemyData.isOutlined = true;  }  }  }   items = GameObject.FindGameObjectsWithTag("Item");  foreach(GameObject itemObject in items){  item = itemObject.GetComponentlt;Itemgt;();  if (item != null) {  if (catsEyeActive amp;amp; player.cateyeLevel == 1) {  enemyData.isOutlined = true;  item.isOutlined = true;  }  }  }   specials = GameObject.FindGameObjectsWithTag("Special");  foreach(GameObject specialObject in specials){  special = specialObject.GetComponentlt;Specialgt;();  if (special != null) {  if (catsEyeActive amp;amp; player.cateyeLevel == 2) {  enemyData.isOutlined = true;  item.isOutlined = true;  special.isOutlined = true;  }  }  }   hiddens = GameObject.FindGameObjectsWithTag("Hidden");  foreach(GameObject hiddenObject in hiddens){  hidden = hiddenObject.GetComponentlt;Hiddengt;();  if (hidden != null) {  if (catsEyeActive amp;amp; player.cateyeLevel == 3 ) {  enemyData.isOutlined = true;  item.isOutlined = true;  special.isOutlined = true;  hidden.isOutlined = true;  }  }  }     }    public void CatsEye(){  if (player.cateye gt;= 1 amp;amp; !catsEyeActive) {   player.cateye -= 1;  StartCoroutine("CatEye");  }  }    IEnumerator CatEye(){  catsEyeActive = true;  yield return new WaitForSeconds(15f);  catsEyeActive = false;  }