Синтаксис
- public static GameObject Find (имя строки);
- public static GameObject FindGameObjectWithTag (строковый тег);
- public static GameObject [] FindGameObjectsWithTag (строковый тег);
- public static Object FindObjectOfType (тип типа);
- public static Object [] FindObjectsOfType (Тип типа);
замечания
Какой метод использовать
Будьте осторожны при поиске GameObjects во время выполнения, поскольку это может быть ресурсоемким. В частности: не запускайте FindObjectOfType или найдите в Update, FixedUpdate или, в более общем плане, в методе, называемом одним или несколькими моментами на кадр.
- Вызовите методы выполнения
FindObjectOfType
иFind
только в случае необходимости -
FindGameObjectWithTag
имеет очень хорошую производительность по сравнению с другими методами на основе строк. Unity хранит отдельные вкладки на помеченных объектах и запрашивает их вместо всей сцены. - Для «статических» GameObjects (таких как элементы пользовательского интерфейса и сборные файлы), созданных в редакторе, используйте сериализуемую ссылку GameObject в редакторе
- Храните свои списки GameObjects в списке или массивах, которыми вы управляете сами
- В общем случае, если вы создаете экземпляр множества GameObjects того же типа, взгляните на Object Pooling
- Кэш ваших результатов поиска, чтобы избежать дорогостоящих методов поиска снова и снова.
Идти глубже
Помимо методов, которые приходят с Unity, относительно легко разработать собственные методы поиска и сбора.
-
В случае
FindObjectsOfType()
вас могут быть ваши скрипты, которые хранят список вstatic
коллекции. Гораздо быстрее перебирать готовый список объектов, чем искать и проверять объекты со сцены. -
Или создайте скрипт, который хранит их экземпляры в
Dictionary
основе строк, и у вас есть простая система тегов, которую вы можете расширить.
Поиск по названию GameObject
var go = GameObject.Find("NameOfTheObject");
Pros | Cons |
---|---|
Легко использовать | Производительность ухудшается по количеству игровых объектов в сцене |
Строки – это слабые ссылки и подозрения на ошибки пользователя |
Поиск по тегам GameObject
var go = GameObject.FindGameObjectWithTag("Player");
Pros | Cons |
---|---|
Возможность поиска как отдельных объектов, так и целых групп | Строки – это слабые ссылки и подозрения на ошибки пользователя. |
Относительно быстрый и эффективный | Код не переносится, поскольку теги жестко закодированы в сценариях. |
Вставка в сценарии в режиме редактирования
[SerializeField]
GameObject[] gameObjects;
Pros | Cons |
---|---|
Отличное выступление | Коллекция объектов статическая |
Портативный код | Может ссылаться только на GameObjects с той же сцены |
Поиск GameObjects с помощью скриптов MonoBehaviour
ExampleScript script = GameObject.FindObjectOfType<ExampleScript>();
GameObject go = script.gameObject;
FindObjectOfType()
возвращаетnull
если ни один не найден.
Pros | Cons |
---|---|
Сильно напечатан | Производительность ухудшается по количеству игровых объектов, необходимых для оценки |
Возможность поиска как отдельных объектов, так и целых групп |
Transform tr = GetComponent<Transform>().Find("NameOfTheObject");
GameObject go = tr.gameObject;
Find
возвращаетnull
если ни один не найден
Pros | Cons |
---|---|
Ограниченная, четко определенная область поиска | Строки – слабые ссылки |
Приветствую Вас, дорогие разработчики. В данной статье мы научимся искать игровые объекту по его имени, и по тегу. Ведь при разработке игр нам довольно часто нужно находить игровые объекты, для дальнейшего выполнения каких-либо действий. Приступим сразу к делу.
Поиск объекта по имени
Для того, чтобы найти объект по его имени, необходимо воспользоваться методом GameObject.Find. Посмотрим реализацию данного метода на примере:
public GameObject obj;
void Awake()
{
obj = GameObject.Find("NameGameObject");
}
Обратите внимание, что в первой строке мы создали переменную obj, чтобы в ней хранить ссылку на игровой объект. А в пятой строке, воспользовавшись методом GameObject.Find, получили сам объект по его имени.
Поиск объекта по тегу
Теперь давайте получим ссылку на наш объект по тегу. Для этого воспользуемся методом GameObject.FindGameObjectWithTag:
public GameObject obj;
void Awake()
{
obj = GameObject.FindGameObjectWithTag("TagName");
}
Как видите, смысл такой же, как и в предыдущем примере. Всё очень просто. Только не забудьте указать тег для Вашего объекта, перед запуском данного скрипта. Иначе объект найден не будет.
Важно: Если в Вашей сцене находится несколько объектов с одинаковыми тегами, то метод GameObject.FindGameObjectWithTag найдёт только самый первый объект. Поэтому, существует ещё один способ, который позволит найти все объекты по указанному тегу.
Поиск массива объектов по тегу
Чтобы найти массив объектов по тегу, воспользуемся методом GameObject.FindGameObjectsWithTag. Вы наверное обратили внимание, что название данного меотда почти 1 в 1 схоже с предыдущим методом, за исключением добавленной быквы s в середине названия.
Рассмотрим пример использования метода GameObject.FindGameObjectsWithTag:
public GameObject[] obj;
void Awake()
{
obj = GameObject.FindGameObjectsWithTag("TagName");
}
Обратите внимание, что при использовании метода GameObject.FindGameObjectsWithTag, в первой строке мы должны оказать, что нам нужен массив объектов, при помощи квадратных скобок [].
I’m trying to mimic FindGameObjectsWithTag
with FindGameObjectsWithName
. I know using tags is faster, but I’m trying create a way to search for objects I spawn with a child object I name on instantiation through the inspector.
My goal is create multiple enemy spawners. My current spawner has a drag and drop variable for enemy prefabs. It looks for enemies tagged “ReSpawn”, then checks if that length is below a value, to start spawning more. I would like to upgrade my current single spawner to still check for enemies named “ReSpawn”, but then check if those respawns have a child object a name specified in the editor. This way, I can set the enemy spawners anywhere (e.g. near water, tall grass, forests, etc), and when I defeat one, the specific spawner will instantiate one of its opponents for that area.
Here is my code, so far:
var ThisSpot:String;
var Oppos : GameObject[];
var OppoCount : GameObject[];
var HowMany = 3;
var spawnSizeArea = 25;
function Start() {
StartCoroutine ("Spawn");
}
function Update () {
OppoCount = GameObject.FindGameObjectsWithTag("Respawn");
// OppoCount = GameObject.FindWithName(ThisSpot); This is what I am trying to achieve
if(OppoCount.length < HowMany) {
StartCoroutine ("Spawn");
}
}
function Spawn() {
var length = Oppos.length-1;
var index = Mathf.Round(length*UnityEngine.Random.value);
curSpawn = Oppos[index];
var xz = Random.insideUnitCircle * spawnSizeArea;
var newPosition = Vector3(xz.x,0,xz.x)+transform.position;
yield WaitForSeconds(Random.Range(70,120));
Instantiate(curSpawn, newPosition, transform.rotation);
// Then I could use these 2 lines of code below to use multiple spawners
//var newOp : GameObject = Instantiate(curSpawn, newPosition, transform.rotation);
//newOp.transform.Find("fighter").gameObject.name=ThisSpot;
StopCoroutine("Spawn");
}
Делал уже раньше такое и вот сейчас тоже, нужно найти все объекты на сцене у которых есть к примеру класс TestObject, делаю так
C# | ||
|
или так
C# | ||
|
а мне в ответ
HTML5 | ||
|
что не так не пойму, подскажите что не так?
Добавлено через 5 минут
отмена, недоглядел, у самого класса не было MonoBehaviour, был просто класс public class TestObject{
мдээ…
жаль нельзя тему удалить, а то мусор получается…
Syntax
- public static GameObject Find(string name);
- public static GameObject FindGameObjectWithTag(string tag);
- public static GameObject[] FindGameObjectsWithTag(string tag);
- public static Object FindObjectOfType(Type type);
- public static Object[] FindObjectsOfType(Type type);
Which method to use
Be careful while looking for GameObjects at runtime, as this can be resource consuming. Especially : don’t run FindObjectOfType or Find in Update, FixedUpdate or more generally in a method called one or more time per frame.
- Call runtime methods
FindObjectOfType
andFind
only when necessary FindGameObjectWithTag
has very good performance compared to other string based methods. Unity keeps separate tabs on tagged objects and queries those instead of the entire scene.- For “static” GameObjects (such as UI elements and prefabs) created in the editor use serializable GameObject reference in the editor
- Keep your lists of GameObjects in List or Arrays that you manage yourself
- In general, if you instantiate a lot of GameObjects of the same type take a look at Object Pooling
- Cache your search results to avoid running the expensive search methods again and again.
Going deeper
Besides the methods that come with Unity, it’s relatively easy to design your own search and collection methods.
-
In case of
FindObjectsOfType()
, you could have your scripts keep a list of themselves in astatic
collection. It is far faster to iterate a ready list of objects than to search and inspect objects from the scene. -
Or make a script that stores their instances in a string based
Dictionary
, and you have a simple tagging system you can expand upon.
Searching by GameObject’s name
var go = GameObject.Find("NameOfTheObject");
Pros | Cons |
---|---|
Easy to use | Performance degrades along the number of gameobjects in scene |
Strings are weak references and suspect to user errors |
var go = GameObject.FindGameObjectWithTag("Player");
Pros | Cons |
---|---|
Possible to search both single objects and entire groups | Strings are weak references and suspect to user errors. |
Relatively fast and efficient | Code is not portable as tags are hard coded in scripts. |
Inserted to scripts in Edit Mode
[SerializeField]
GameObject[] gameObjects;
Pros | Cons |
---|---|
Great performance | Object collection is static |
Portable code | Can only refer to GameObjects from the same scene |
Finding GameObjects by MonoBehaviour scripts
ExampleScript script = GameObject.FindObjectOfType<ExampleScript>();
GameObject go = script.gameObject;
FindObjectOfType()
returnsnull
if none is found.
Pros | Cons |
---|---|
Strongly typed | Performance degrades along the number of gameobjects needed to evaluate |
Possible to search both single objects and entire groups |
Find GameObjects by name from child objects
Transform tr = GetComponent<Transform>().Find("NameOfTheObject");
GameObject go = tr.gameObject;
Find
returnsnull
if none is found
Pros | Cons |
---|---|
Limited, well defined search scope | Strings are weak references |