Проверка единства всех объектов с одним и тем же тегом

#c# #unity3d

#c# #unity3d

Вопрос:

Я разрабатываю поисковую игру, в которой игроки должны искать определенные объекты. Всякий раз, когда целевой объект найден и поднят, игрок выигрывает и переходит на следующий уровень. Я пометил целевые объекты как «TargetObj». Я успешно реализовал это, когда нужно искать только один объект. Я хочу изменить свой код, чтобы включить случаи, когда нужно искать несколько объектов. Вот мой код :

 public void someFunction() {  //if we press the button of choice  if (Input.GetKeyDown(KeyCode.Space)) {  //and we're not holding anything  if (currentlyPickedUpObject == null) {  //and we are looking an interactable object  if (lookObject != null) {  PickUpObject();  }  } else { //if we press the pickup button and have something, we drop it  BreakConnection();  }  } }  /* ommitted lines */  public void PickUpObject() {  if (GameObject.FindGameObjectsWithTag("TargetObj").Length == 1 amp; lookObject.tag == "TargetObj") {  physicsObject = lookObject.GetComponentInChildrenlt;PhysicsObjectsgt;();  currentlyPickedUpObject = lookObject;  pickupRB = currentlyPickedUpObject.GetComponentlt;Rigidbodygt;();  pickupRB.constraints = RigidbodyConstraints.FreezeRotation;  physicsObject.playerInteractions = this;  winUI.SetActive(true);  Time.timeScale = 0f;  SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex   1);  Time.timeScale = 1f;  } else if (GameObject.FindGameObjectsWithTag("TargetObj").Length gt; 1) {    } else {  physicsObject = lookObject.GetComponentInChildrenlt;PhysicsObjectsgt;();  currentlyPickedUpObject = lookObject;  pickupRB = currentlyPickedUpObject.GetComponentlt;Rigidbodygt;();  pickupRB.constraints = RigidbodyConstraints.FreezeRotation;  physicsObject.playerInteractions = this;  } }  

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

else if (GameObject.FindGameObjectsWithTag("TargetObj").Length gt; 1)

Как это реализовать (если игрок подобрал все объекты тега «TargetObj», перейдите на следующий уровень.)?

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

1. в общем, вы должны свести вызов GameObject.FindGameObjectsWithTag("TargetObj") к минимуму, а скорее кэшировать и повторно использовать результат .. и тогда это звучит так, как будто вы хотите сделать foreach цикл …

2. Я не понял, что вы имеете в виду, сводя это к минимуму?

3.Не используйте его, если это возможно 😉 И особенно не два раза подряд .. в настоящее время вы используете GameObject.FindGameObjectsWithTag("TargetObj") только для проверки его длины .. затем, если это не == 1 так, вы снова используете GameObject.FindGameObjectsWithTag("TargetObj") для проверки второго случая … скорее кэшируйте его один раз и повторно используйте массив, как var taggedObjects = GameObject.FindGameObjectsWithTag("TargetObj"); if(taggedObjects.Length == 1){ ...} else if (taggedObjects.Length gt; 1) { ... }

4. Кстати, остальная часть вашего вопроса довольно неясна .. каков вариант использования и что должно произойти с этими несколькими объектами?

5. ладно, я понимаю, что ты имеешь в виду. Спасибо вам за ваше объяснение. Но могу ли я узнать причину? Я имею в виду, почему я должен избегать такого использования?

Ответ №1:

Быстрый способ сделать это-сохранить счетчик выбранных объектов. Затем, если счетчик равен количеству объектов с тегом «TargetObj», то игрок выигрывает. В качестве фрагмента вы можете получить что-то вроде этого:

 Gameobject[] targetObjects; // an array where you will keep your objects with "TargetObj" tag Listlt;GameObjectgt; targetObjectsList;  void Start() {  targetObjects = GameObject.FindGameObjectsWithTag("TargetObj");  targetObjectsList = new Listlt;GameObjectgt;(); }  .  .  .  // In your method (You didn't put all your code so I will use your snippet) if (Input.GetKeyDown(KeyCode.Space))  {  //and we're not holding anything  if (currentlyPickedUpObject == null)  {  //and we are looking an interactable object  if (lookObject != null )  {  PickUpObject();    // I suppose that "lookObject" is the gameobject that you want to pickup. If not, replase this variable with the right gameobject.  if(!targetObjectsList.Contains(lookObject.gameObject))  {  targetObjectsList.Add(lookObject.gameObject);   if (targetObjectsList.Count == targetObjects.Length)  {  //Finish the game  winUI.SetActive(true);  Time.timeScale = 0f;  SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex   1);  Time.timeScale = 1f;  }  }  }  }  }  //if we press the pickup button and have something, we drop it  else  {  BreakConnection();  }  }  

Затем вы изменяете свой метод PickUpObject, просто чтобы выбирать и отбрасывать объекты.

Мне жаль, если я что-то упустил. Я написал это без редактора и не тестировал код, поэтому, пожалуйста, скажите мне, есть ли что-то, чего мне не хватает.

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

1. Привет, извините за мой поздний ответ. Я проверил ваш код, он работает, но у него странная проблема. В настоящее время у меня есть 2 объекта с тегом «TargetObj». Поэтому, чтобы выиграть, мне нужно выбрать оба и один из них дважды. Я не знаю, почему это происходит.

2. Я также протестировал один объект, и он один и тот же, чтобы выиграть, мне нужно взять его дважды.

3. Привет. Я отредактировал свой ответ. Скажи мне, есть ли сейчас какие-либо проблемы.

4. Хорошо, я проверю это и дам вам знать

5. Я проверил ваш код. Это работает лучше, чем раньше, но все еще работает не полностью. У меня в текущей сцене 3 разных объекта с тегом «TargetObj». когда я выберу каждого из них, как только выиграю. и это хорошо. Однако, если я выберу один из 3 раз, я тоже выиграю. Что неверно. таким образом, в настоящее время количество собираемых объектов должно быть столько же, сколько объектов этого тега. Это не совсем то, чего я хочу.