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

Обновлено: 06.07.2024

Я хочу получить доступ к Image дочернему компоненту префаба.

Я попробовал следующий код:

Тем не менее, приведенный выше код обращается к сценарию изображения кнопки (встроенный). Не компонент Image UI. Как я могу получить доступ к компоненту UI Image (дочерний)?

3 ответа

GetComponentInChildren также вернет компонент в самом gameObject.

Возвращает компонент типа Type в GameObject или любого из его дочерних элементов, используя поиск в глубину.

Если индекс дочерних GameObject 1 Text и 2 Image фиксирован. Их можно получить с помощью Transform.GetChild(index) .

Если порядок не фиксирован, используйте Transform.Find(childName) .

самое безопасное решение:

Перетащите ваш префаб на сцену и прикрепите скрипт к кнопке GameObject :

Таким образом, вы можете получить доступ к тексту и изображению, как:

Прежде чем получить доступ к дочернему объекту, убедитесь, что этот дочерний объект включен в prefab, прежде чем включать или отключать его после создания экземпляра. Как и в моем случае, у меня был игровой объект UI Text с дочерним объектом изображения. Я отключил его в префабе с надеждой включить его по ссылке в скрипте после его создания. Это сработало, только если я включил компонент изображения (дочерний элемент) в prefab.

Некоторые игры имеют постоянное количество объектов на сцене, однако обычно персонажи, пули, сокровища и другие объекты создаются и удаляются во время игры. В Unity, игровой объект (GameObject) может быть создан через функцию Instantiate, которая делает копию существующего объекта. Объект, который мы будем клонировать, должен быть prefab’ом и сохранен в папке Resources.

Сейчас ты напишешь пару скриптов, с помощью которых можно научиться создавать (spawn’инть) игровые объекты, например, для того, чтобы реализовать механику вот такой ловушки:

Подготовка

Тебе понадобятся четыре игровых объекта и скрипт, с которым ты уже знаком:

  1. Камень, несколько копий которого мы будем сбрасывать на Игрока — Stone.
  2. Объект, который соответствует еще не сработавшей ловушке — TrapOn.
  3. Объект, который соответствует уже сработавшей ловушке — TrapOff.
  4. Объект, который будет запускать ловушку — TrapSwitch.
  5. Скрипт OnTriggerSceneLoader.7z — он будет перезагружать уровень, когда Stone упадет (коснется) Игрока.

Stone

По нашему плану нам понадобятся камни, которые будут создаваться над головой Игрока. Выбери 3D-модель, которая тебе понравилась, добавь ей компоненты Rigidbody и два коллайдера: Capsule и Box. Box коллайдер должен быть чуть больше, чем Capsule, а также иметь включенным свойство Trigger.

После этого добавь этому игровому объекту скрипт OnTriggerSceneLoader и укажи в его свойствах название текущей сцены (а еще не забудь добавить ее в Build Settings).

Не забудь сохранить объект Stone, как prefab, в папке Resources!

Программирование

Тебе понадобятся два новых скрипта, чтобы все работало как нужно: Spawner.cs и TrapSwitch.cs

Spawner

Как мы уже говорили, в Unity есть функция Instantiate, которая делает копию существующего объекта:

В нашем случаем наш объект будет физическим, так что ты можешь сразу объявить Rigidbody, также понадобится переменная, в которой ты будешь указывать необходимое количество клонов:

Теперь нужно написать публичный метод, который ты будешь вызывать скриптом TrapSwitch.cs, стандартные методы Update() и Start() нам не понадобятся, так что их можно удалить:

Чтобы выполнить функцию Instantiate несколько раз, используй цикл, например, do while:

Технически, скрипт готов, но, если оставить все как есть, то во время выполнения метода Spawn(), практически, одновременно в одной точке появятся все amount (число) клоны. Из-за того, что наши клоны содержат в себе компоненты Rigidbody и коллайдер, клоны просто разлетятся в разные стороны, что выглядит не очень. При этом, шанс, что хотя бы один клон-камень попадет в Игрока будет очень низок. Поэтому добавь немного рандома и сделай так, чтобы каждый следующий камень создавался выше предыдущего на i:

Теперь все работает как нужно. Продолжим.

TrapSwitch

TrapSwitch будет размещен на объекте с триггером, когда Игрок будет его касаться, TrapSwitch будет запускать метод Spawn() у объекта Spawner. Напомним про коллайдеры и триггеры:

Триггер — это зона срабатывания определенных действий, когда объект входит в эту зону, находится в ней или выходит за ее пределы.

Сейчас тебе понадобиться метод OnTriggerEnter. Он выполняется, когда объект только вошел в зону триггера один раз. Создай такой скрипт:

Ты собираешься взаимодействовать с двумя игровыми объектами и объектом Spawner. Их нужно объявить:

Теперь необходимо убедиться, что объект, который войдет в триггер является Игроком. Это можно сделать, используя тег, как в OnTriggerSceneLoader:

Теперь последовательно напиши все необходимые команды внутрь условия: удаление (уничтожение) объекта TrapOn, включение объекта TrapOff, выполнение метода Spawn() и удаление (уничтожения) себя.

Все скрипты написаны. Поздравляем! Осталось правильно разместить все объекты на сцене и не забыть указать им друг на друга.

Есть ли способ сделать это?

Если вы используете Rigidbody с персонажем, вы можете получить это из коробки. :)

Итак, ваша иерархия может выглядеть так:

  • Персонаж (имеет Rigidbody и управляющий скрипт)
    • ребенок (может быть, есть коллайдеры)
      • внук (может быть, есть коллайдеры)

      Если вам нужно выяснить, кто из ваших дочерних коллайдеров участвовал в столкновении, вы можете сделать это следующим образом:

      Одним из способов решения этой проблемы было бы иметь два сценария: один для объекта Enemy и другой для дочернего объекта (который необходимо назначить дочерним объектам Enemy).

      Родительский скрипт

      Дочерний скрипт

      Таким образом, вы должны получать уведомления всякий раз, когда происходит столкновение с ребенком

      Вы можете просто передать верхний объект дочерним элементам и вызвать функцию непосредственно на нем. Это гарантирует, что вам не нужно полагаться на родительское распространение. Таким образом, вы не в конечном итоге делать глупые вещи, как transform.parent.parent

      Однако вы можете автоматизировать этот процесс с помощью GetComponentInParent . Это возвращает первый найденный скрипт. Затем кешируйте это в вашем объекте столкновения, непосредственно вызывайте функции для указанного кешируемого объекта.

      В качестве альтернативы вы можете использовать UnityEvents (не используйте Messages) для привязки функций к дочернему объекту. С помощью событий единства вы можете добавить любого произвольного слушателя, чтобы вы могли сделать больше, чем просто уведомить объект верхнего уровня о попадании дочернего объекта.

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

      Ответы (2 шт):

      GetChild - Returns a transform child by index.

      Find - Finds a child by name and returns it.

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

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

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

      Читайте также: