Как обратиться к дочерним объектам unity
Перейти к содержимому

Как обратиться к дочерним объектам unity

  • автор:

Как обратиться к дочернему объекту через родительский?

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

Вадим Мороз's user avatar

GetChild — Returns a transform child by index.

Find — Finds a child by name and returns it.

Valera Kvip's user avatar

Если вам нужно получить ссылку на все дочерние объекты то сделать это можно непосредственно из родительского Transform который хранит всю информацию об иерархии вложенных объектов. При помощи childCount можно узнать количество детей, а при помощи hierarchyCount количество всех объектов вложенной иерархии. Зная количество потомков вы можете перебором получить доступ к любому из них посредством функции GetChild.

Поиск через Find может оказаться более ресурсоемким, поэтому его не рекомендуется использовать в Update или FixedUpdate . К тому же можно просто перебрать все вложенные элементы просто через энумератор Transform:

Еще один вариант это если вы собираетесь работать с информацией в компонентах детей найти их все скажем на Start и сохранить на них ссылки чтобы работать с ними напрямую (в том случае если иерархия объектов в сцене не изменяется). Найти вложенные компоненты можно при помощи метода GetComponentsInChildren которая вернет вам все компоненты у родителя и детей вашего Transform по заданному типу в виде массива ссылок.

Доступ к дочернему объекту

Есть префабы с разным количеством дочерних объектов.
В старте я к некоторым из этих префабов через код рандомно присоединяю ещё по одному рандомному дочернему объекту из определённого списка предметов .
Хочу чтобы при старте, префабы к которым добавился новый дочерний объект, знали что он к ним присоединился.
Знаю про функции Transform.Find, но наверно она не подходит, так как имена у новых дочерних объектов разные.

Доступ к объекту
Доброго времени суток. Начал изучать юнити, но никак не могу понять, как получить доступ к объекту.

Как получить доступ к объекту из сцены?
Прикрепил скрипт Click к префабу. Для работы скрипта нужен объект из сцены со скриптом Score, но.

Как прикрепить линию к объекту и провести к другому объекту?
Привет. Вот вариант с помощью метода Gizmos.DrawLine. Как видите линия проходит с центра одного.

Доступ актёра к дочернему прецеденту (диаграмма прецедентов)
Подскажите: может ли актёр вызывать сразу дочерний прецедент, минуя родительский? Ситуация такая.

Ещё вопрос в эту тему.

Мне нужно было получить компонент Animator у дочернего объекта с тегом "Items".
Сделал это таким образом:

Лучший ответСообщение было отмечено Blascovich как решение

Решение

Сообщение от Blascovich

Добрый день, что-то перебрал в 2019.3 разные методы не могу допереть как искать внутри объекту по нужному тегу.

У меня объект, структура такая:
— Главный пустой объект с прицепленными компонентами Корпус 0.
внутри ещё два объекта:
объект 1
объект 2

так я получаю объект 2. Мне это и нужно.
Но дальше внутренних объектов будет больше. Все с уникальными тегами.
Подскажите как сделать не GetChild(1) (по ID), а поиск по тегу?.

1max!
Использовать функцию в виде как есть ? Как ты написал?
Просто я пытался подобное сделать по примеру выше,
там где приводился пример : foreach (Transform child in gameObject.transform)
Но на это он при поиске по тегу мне отвечает что объект ещё не заинстантиэнтин. Типа не появился. Хотя он есть.
Не понимаю причин.

squakoon
Немного не понял, так будет выглядеть команда ?

об2 = parentTransform.Cast<Transform>().Where(child => child.CompareTag(SomeTag))
или
об2 = gameObject.parentTransform.Cast<Transform>().Where(child => child.CompareTag(SomeTag))
Мне нужна итоговая ссылка на объект дочерний, для доступа к компонентам.

Не понял.
Я не могу перенести этот метод ?
Зачем мне класс создавать ?
У меня
Объект
— дочерний
— дочерний(с тегом)

найти дочерний с тегом(по названию тега)
Скрипт висит на основном объекте. Тоесть так? :

Возможно такие конструкции можно применить для каких то сложных задач.
Я пока их понять не могу. Как я уже говорил мне просто нужен был дочерний
объект чтобы я мог с ним по ссылке сделать что угодно.
Но всё равно спасибо, помогли натолкнуться на новые идеи.

Сначала я пытался искать по тегу :
if (GetComponentInChildren<Transform>().GetChild(number).tag == "child")
Перебирая number в цикле (number считал как GetComponentInChildren<Transform>().childCount
И вроде всё логично и должно было работать, но "UnityException: Transform child out of bounds"
Такое должно быть только если childCount тупо врёт. Иногда поражает логика простых вещей которая не работает.

Для тех у кого схожие задачи, в итоге всё решается одной строкой:
childObject = GetComponentInChildren<Transform>().Find("childName");
Поиск осуществляется по имени объекта в иерархии родительского объекта.

Управление игровыми объектами (GameObjects) с помощью компонентов

В редакторе Unity вы изменяете свойства Компонента используя окно Inspector. Так, например, изменения позиции компонента Transform приведет к изменению позиции игрового объекта. Аналогично, вы можете изменить цвет материала компонента Renderer или массу твёрдого тела (RigidBody) с соответствующим влиянием на отображение или поведение игрового объекта. По большей части скрипты также изменяют свойства компонентов для управления игровыми объектами. Разница, однако, в том, что скрипт может изменять значение свойства постепенно со временем или по получению ввода от пользователя. За счет изменения, создания и уничтожения объектов в заданное время может быть реализован любой игровой процесс.

Обращение к компонентам

Наиболее простым и распространенным является случай, когда скрипту необходимо обратиться к другим компонентам, присоединенных к тому же GameObject. Как упоминалось во разделе Введение, компонент на самом деле является экземпляром класса, так что первым шагом будет получение ссылки на экземпляр компонента, с которым вы хотите работать. Это делается с помощью функции GetComponent. Типично, объект компонента сохраняют в переменную, это делается в C# посредством следующего синтаксиса:

В UnityScript синтаксис немного отличается:

Как только у вас есть ссылка на экземпляр компонента, вы можете устанавливать значения его свойств, тех же, которые вы можете изменить в окне Inspector:

Дополнительная возможность, недоступная в окне Inspector — вызов функций экземпляра компонента:

Имейте ввиду, что нет причины, по которой вы не можете иметь больше одного пользовательского скрипта, присоединенного к одному и тому же объекту. Если вам нужно обратиться к одному скрипту из другого, вы можете использовать, как обычно, GetComponent, используя при этом имя класса скрипта (или имя файла), чтобы указать какой тип Компонента вам нужен.

Если вы попытаетесь извлечь Компонент, который не был добавлен к Игровому Объекту, тогда GetComponent вернет null; возникнет ошибка пустой ссылки при выполнении (null reference error at runtime), если вы попытаетесь изменить какие-либо значения у пустого объекта.

Обращение к другим объектам

Пусть иногда они и существуют изолированно, все же, обычно, скрипты отслеживают другие объекты. Например, преследующий враг должен знать позицию игрока. Unity предоставляет несколько путей получения других объектов, каждый подходит для конкретной ситуации.

Связывание объектов через переменные

Самый простой способ найти нужный игровой объект — добавить в скрипт переменную типа GameObject с уровнем доступа public:

Переменная будет видна в окне Inspector, как и любые другие:

Теперь вы можете перетащить объект со сцены или из панели Hierarchy в эту переменную, чтобы назначить его. Функция GetComponent и доступ к переменным компонента доступны как для этого объекта, так и для других, то есть вы можете использовать следующий код:

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

Соединение объектов через переменные наиболее полезно, когда вы имеете дело с отдельными объектами, имеющими постоянную связь. Вы можете использовать массив для хранения связи с несколькими объектами одного типа, но связи все равно должны быть заданы в редакторе Unity, а не во время выполнения. Часто удобно находить объекты во время выполнения, и Unity предоставляет два основных способа сделать это, описанных ниже.

Нахождение дочерних объектов

Иногда игровая сцена может использовать несколько объектов одного типа, таких как враги, путевые точки и препятствия. Может возникнуть необходимость отслеживания их в определенном скрипте, который управляет или реагирует на них (например, все путевые точки могут потребоваться для скрипта поиска пути). Можно использовать переменные для связывания этих объектов, но это сделает процесс проектирования утомительным, если каждую новую путевую точку нужно будет перетащить в переменную в скрипте. Аналогично, при удалении путевой точки придется удалять ссылку на отсутствующий объект. В случаях, наподобие этого, чаще всего удобно управлять набором объектов, сделав их дочерними одного родительского объекта. Дочерние объекты могут быть получены, используя компонент Transform родителя (так как все игровые объекты неявно содержат Transform):

Вы можете также найти заданный дочерний объект по имени, используя функцию Transform.Find:

Это может быть полезно, когда объект содержит дочерний элемент, который может быть добавлен или удален в игровом процессе. Хороший пример — оружие, которое может быть подобрано и выброшено.

Как обратиться к дочерним объектам unity

denri11 01 авг 2012, 23:52

Re: Как обратиться.

DbIMok 02 авг 2012, 00:58

Re: Как обратиться.

denri11 16 авг 2012, 14:54

Re: Как обратиться.

DokSergey 16 авг 2012, 14:58

Re: Как обратиться.

DokSergey 16 авг 2012, 15:04

Re: Как обратиться. [РЕШЕНО]

seaman 16 авг 2012, 17:55

Re: Как обратиться. [РЕШЕНО]

DokSergey 16 авг 2012, 18:01

Ошибся.
GameObject родителя — transform.parent.gameObject

Re: Как обратиться. [РЕШЕНО]

piligrin 19 дек 2014, 20:38

В Родителе есть два объекта: А(с коллайдером) и В(внутри объекта С). На В висит этот скрипт . Как в скрипте В указать коллайдер объекта А? Нужно при столкновении игрока с триггером на А, повернуть объект В. Ну честное слово не получается.

Transform myParent ;
void Start ( ) {
Collider = myParent. collider ;
}

void OnTriggerEnter ( Collider other ) {
if ( other. gameObject . tag == "Player" ) {
enter = true ;
}

Re: Как обратиться. [РЕШЕНО]

piligrin 20 дек 2014, 00:04

Я пока так сделал. На А-объекте проверка триггера.Если игрок в триггере, отсылаем к В-объекту сообщение об этом. Но это лишний скрипт придётся вешать, не хотелось бы, и так всего понавешено. Может можно сразу из одного скрипта обратиться к чужому коллайдеру? Или из объекта А крутить объект В,если Игрок в триггере объекта А ?

if ( open ) {
GetComponentInChildren < DoorOpen > ( ) . ope = true ;
}
if ( ! open ) {
GetComponentInChildren < DoorOpen > ( ) . ope = false ;
}

void OnTriggerEnter ( Collider other ) {
if ( other. gameObject . tag == "Player" ) {
enter = true ;
}
}

Re: Как обратиться. [РЕШЕНО]

DonTTGnev 20 дек 2014, 04:29

Re: Как обратиться. [РЕШЕНО]

piligrin 20 дек 2014, 09:28

Re: Как обратиться. [РЕШЕНО]

Ingeneer 01 окт 2016, 05:38

Even though i never used GetComponentInParent i guess it does work similar to GetComponentInChildren. What most don't know is that it starts searching on the given object and not on the first child or in the case of GetComponentInParent on the parent. So using this method to find a Transform will return the Transform of the object and not of the parent.

Both methods are actually badly named. They should be called something like:

If you just want to access the transform of the direct parent object, use:

Character = transform.parent;
If you want to access the top most parent, use:

У кого с английским плохо, тут парень говорит о том, что название GetComponentInParent не отображает реального назначения функции, что скорее ее стоило бы назвать «ИскатьКомпонентВыше», чем «ВзятьКомпонентВРодителе». Объясняет он это тем, что функция начинает поиск компонента не с родительского объекта, а с объекта, к которому прикреплен скрипт, уже далее продвигаясь вверх по иерархии объектов, и потому возвращает нам прежде компонент объекта, вместо компонента из родителя. В документации при этом не поясняется эта особенность у функции, что она начинает рекурсию с объекта, а не с родителя.

Другой парень провел эксперимент:

Взял два GameObject’a Root и Child, поместив Child в Root.

Изображение

В Child он поместил следующий скрипт:

var t1 = transform . parent . GetComponent < Transform > ( ) ;
var t2 = GetComponentInParent < Transform > ( ) ;

И вот что ему выдало в логах при запуске сцены

Изображение

Transform, полученный через GetComponentInParent<>() принадлежит объекту, на который прикреплен скрипт, а не родителю. Конечно, делал он это на JS, но и проверив на C# получилось все тоже самое.

Вывод: при одиночном выборе родителя надо пользоваться transform’ом.

Обращение же к дочернему объекту можно осуществлять через функцию GetChild(n), где n — порядковый номер дочернего объекта, начиная с 0 (0 означает первый объект). Пример:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *