#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 раз, я тоже выиграю. Что неверно. таким образом, в настоящее время количество собираемых объектов должно быть столько же, сколько объектов этого тега. Это не совсем то, чего я хочу.