Использование компонентов.
Компоненты — основные элементы поведения объектов в игре. Они — функциональная часть любого Объекта. Если вы еще не поняли взаимоотношений Компонентов и Объектов — прочитайте страницу Объекты игры.
Объект игры — контейнер для различных компонентов. По умолчанию все объекты автоматически получают компонент Transform. Это потому, что Трансформ определяет где расположен Объект, как он повернут и масштабирован. Без этого компонента не имеет местоположения в мире. Попробуйте теперь для примера создать пустой Объект. Щелкните в меню GameObject->Create Empty (Объект->создать пустой). Выберите новый объект и посмотрите в Инспектор.
Каждый пустой объект имеет компонент Transform
Помните, что Вы всегда в Инспекторе можете увидеть какие компоненты прикреплены к выбранному Объекту. Когда компонент добавляется или удаляется Инспектор всегда показывает Вам изменения. В Инспекторе Вы всегда можете изменить свойства компонента (включая скрипты).
Добавление компонентов
Вы можете добавить Компоненты к выбранному Объекту игры через меню компонентов. Мы попробуем сделать это сейчас добавив Ригидбоди к только что созданному Объекту. Выберите объект и перейдите в меню Component->Physics->Rigidbody. После этого Вы увидите свойства компонента Ригидбоди в Инспекторе. Если Вы нажмете Play Вы можете удивиться. Попробуйте и увидите как Ригидбоди изменило поведение объекта, добавив к нему новую функциональность (смотрите на y-компоненту позиции объекта — она уменьшается. Это потому что физический движок теперь заставляет объект падать под действием гравитации).
Пустой объект с прикрепленным компонентом Rigidbody
Другая возможность добавить компонент — активировать Браузер компонентов, который открывается кнопкой Добавить компонент (Add Component) в Инспекторе.

Браузер позволяет перемещаться удобно по категориям, а также имеет окно поиска, которое можно использовать для поиска компонентов по имени.
Вы можете прикрепить любое число или комбинацию компонентов к одному Объекту игры. Некоторые компоненты работают в комбинации с другими. Например Ригидбоди работает с Коллайдером. Ригидбоди управляет трансформациями через физический движок NVIDIA PhysX, а коллайдер позволяет Ригидбоди взаимодействовать с другими коллайдерами.
Если Вы хотите узнать больше о использовании отдельных компонентов, Вы можете прочитать о них в Справочнике компонентов. Вы можете также перейти к описанию компонента прямо из Юнити, нажав знак ? у заголовка компонента в Инспекторе.
Редактирование компонентов
Один из самых крутых плюсов применения компонентов — гибкость. Когда Вы прикрепляете компонент к Объекту, появляется возможность настройки различных свойств компонента в редакторе перед сборкой игры, или из скрипта во время запуска игры. Есть два главных типа свойств — Значения и Ссылки.
Посмотрите на рисунок ниже. Это пустой Объект с компонентом Источник Аудио (Audio Source). Все значения компонента в Инспекторе установлены по умолчанию.

Этот компонент содержит одно свойство Ссылки и семь свойств — Значений. Ссылка — Аудио Клип (Audio Clip). Когда данный аудио источник включается, он пытается проиграть аудио файл на который ссылается свойство Audio Clip. Если ссылка не установлена — будет ошибка отсутствия аудио. Вы должны указать ссылку на файл в Инспекторе. Это можно сделать просто перетащи аудио файл из Окна Проекта на свойство, или можно использовать Object Selector.
Теперь свойство Audio Clip ссылается на файл звукового эффекта
Компоненты могут включать ссылки на любой другой тип компонента, на Объект игры или на ассет. Вы можете почитать дополнительно о назначении ссылок на странице Назначение ссылок.
Остальные свойства Аудио клипа — Значения. Они могут быть настроены напрямую в Инспекторе. Эти свойства у Аудиоклипа — переключатели, числовые значения, выпадающие поля. Однако такие свойства могут быть также текстовыми строками, цветом, кривыми или другими типами. Вы можете почитать дополнительно о редактировании свойств значений на странице Редактирование свойств значений.
Копирование и вставка установок компонентов
Контекстное меню для компонента имеет строки для копирования и вставки его значений.

Скопированные значения могут быть вставлены в существующие компоненты. Альтернативно — Вы можете использовать меню Вставить компонент как новый (Paste Component As New) для создания нового компонента с теми же значениями.
Тестирование свойств
Когда Вы в режиме игры, Вы можете свободно изменять свойства любого объекта в Инспекторе. Например Вы можете захотеть поэкспериментировать с различными свойствами прыжка. Если Вы создадите свойство высоты прыжка (Jump Height) в Вашем скрипте, Вы можете войти в режим игры, изменить значение и нажать кнопку прыжка, чтобы увидеть что изменилось. Затем без выхода из режима игры Вы можете изменять его снова, чтобы подобрать нужное. Когда Вы выйдете из режима игры Ваше свойство вернется к установленному до входа в игру. Это свойство дает Вам потрясающую мощь для экспериментирования и настройки Вашей игры без с малыми затратами времени. Испытайте это с любым свойством — Вы будете впечатлены.
Изменение порядка компонентов
Порядок, в котором располагаются компоненты в Инспекторе в большинстве случаев не имеет значения. Однако для некоторых компонентов, таких как Эффекты порядок важен. Контекстное меню Сдвинуть вверх и сдвинуть вниз позволяет Вам изменить порядок, если необходимо.

Удаление компонентов
Если Вы хотите удалить компонент щелкните правой мышкой на заголовке компонента в инспекторе и выберите Удалить компонент (Remove Component). Или Вы можете щелкнуть по иконке рядом с ? в заголовке компонента. Все свойства и установки будут потеряны и это действие отмене не подлежит, так что будьте совершенно уверены в своих действиях, когда удаляете компонент.
Introduction to components
Components are the functional pieces of every GameObject. Components contain properties which you can edit to define the behavior of a GameObject. For more information on the relationship between components and GameObjects, see GameObjects The fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
See in Glossary .
To view a list of the components attached to a GameObject in the Inspector A Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary window, select a GameObject in either the Hierarchy window or the Scene A Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary view.
You can attach many components to a GameObject, but every GameObject must have one and only one Transform component. This is because the Transform component dictates the GameObject’s location, rotation, and scale. To create an empty GameObject, select GameObject > Create Empty. When you select the new GameObject, the Inspector displays the Transform component with default values.
Empty GameObjects have a Transform component
Базовые концепции Unity для программистов
Привет, Хабр! При проработке темы Unity мы нашли интересный блог, возможно, заслуживающий вашего более пристального внимания. Предлагаем вам перевод статьи о базовых концепциях Unity, также опубликованный на портале Medium
Если вы обладаете опытом программирования и пытаетесь вкатиться в разработку игр, порой бывает непросто найти такие учебные материалы, в которых в достаточной степени объясняется необходимый контекст. Вероятно, придется выбирать между материалами, в одних из которых описана парадигма ООП, в других — язык C# и концепции Unity, либо сразу начинать с продвинутых руководств; в последнем случае придется самостоятельно дедуктивно выводить базовые концепции.
Поэтому, чтобы отчасти заполнить этот пробел, я решил написать серию статей Unity for Software Engineers. Это первая из них. Статья рассчитана на читателей, имеющих представление о программировании и программной архитектуре, в особенности на тех, кому близок тот же подход к обучению, что и мне: начинать с основ и постепенно идти вверх.
Я начал путь в программировании около 17 лет назад, открыв для себя Game Maker. Многие часы потратил на самостоятельное программирование маленьких игр и инструментов, в процессе всерьез увлекшись программированием.
Однако с тех пор ландшафт игровой разработки серьезно изменился. Когда я попробовал Unity после долгой паузы с игровой разработкой, мне больше всего хотелось понять базовые концепции: из каких кирпичиков строится игра в Unity? Что нужно знать о принципах представления этих кирпичиков в памяти или на диске? Как организован идиоматический код? Какие паттерны предпочтительны?
Сцена
Сцена – это самый крупный блок, описывающий организацию объектов в памяти. В сценах содержатся объекты, из которых состоит ваша игра.
В базовом случае сцена представляет отдельно взятый уровень вашей игры, где в любой конкретный момент времени загружена одна сцена. В более продвинутых сценариях у вас одновременно могут быть активны две или более сцен. В таком случае сцены можно дополнительно загружать в память или выгружать. Особенно удобно загружать во время геймплея несколько сцен, когда строишь крупномасштабный мир; когда держишь отдаленные области игрового мира на диске, а не в памяти, проще выдерживать стоящие перед вами требования по производительности.

Редактор сцен Unity, в котором загружена задаваемая по умолчанию пустая сцена в режиме 3D. В пустых сценах Unity3D по умолчанию содержатся объекты Main Camera (Главная Камера) и Directional light (Направленный свет).

Пример сцены в редакторе Unity; здесь выделено несколько объектов. Такое представление сцены можно использовать для редактирования уровней в игре.
Каждый игровой объект в Unity должен находиться в сцене.
Игровые объекты
Игровой Объект (в коде GameObject ) – один из базовых кирпичиков, из которых строится игра.
В виде игровых объектов можно представлять как физические сущности, наблюдаемые в игре (напр., персонаж, грунт, дерево, ландшафт, свет, оружие, пуля, взрыв) так и метафизические (напр., менеджер снаряжения, контроллер мультиплеерного режима, т.д.).
У каждого игрового объекта есть значения положения и поворота. Для метафизических объектов они не имеют значения.
Допускается вложение игровых объектов друг в друга. Положение и поворот каждого объекта отсчитывается относительно его родительского объекта. Объект, расположенный непосредственно в сцене, позиционируется относительно «мировых координат».

Группа объектов, совместно вложенных в сцене и объединенных в пустом объекте “Interior_Props”, сделано в целях структурирования
Есть много причин, по которым вам может понадобиться вложение объектов. Например, вы можете решить, что со структурной точки зрения будет целесообразно поместить всю вашу «окружающую среду» (например, отдельные элементы, из которых состоит город или деревня) в пустой родительский объект. Таким образом, окружающую среду можно «компактифицировать» и вместе со всем представлением данной сцены перенести куда требуется при разработке игры.

Группа объектов, вложенных в объект «игрок». Здесь мы видим оружие игрока, его аватарку и различные элементы пользовательского интерфейса, отображаемые вокруг игрока
Вложение объектов может быть значимым и с функциональной точки зрения. Например, в объекте «Car» может содержаться код, управляющий как скоростью, так и поворотами машины в целом. Но у него могут быть отдельные дочерние объекты, представляющие четыре колеса (причем, все колеса будут крутиться независимо), корпус машины, окна, т.д. При перемещении родительского объекта «Car» будут двигаться и все его дочерние объекты, сохраняющие ориентацию относительно родительского объекта и относительно друг друга. Например, мы можем запланировать, что персонаж открывает дверцу, и это действие касается именно дверцы, а не всей машины.
Компоненты (и моноповедения)

Объект «Warrior» с предыдущего скриншота показан над окном «Инспектор» в интерфейсе Unity. Каждый из проиллюстрированных разделов (напр., Animator, Rigidbody, Collider) – это компоненты, слагающие этот объект
Каждый игровой объект состоит из компонентов.
Компонент реализует четко определенный набор поведений, необходимых, чтобы мог выполниться GameObject . Все, благодаря чему объект получается таким, каков он есть — это вклад компонентов, из которых он состоит:
- У единственного «видимого» элемента машины будет компонент Renderer, который отрисовывает машину и, вероятно, компонент Collider, задающий для нее границы столкновений.
- Если машина представляет персонажа, то у самого объекта car может быть Player Input Controller (Контроллер ввода от персонажа), принимающий все события, связанные с нажатиями клавиш, и транслирующий их в код, отвечающий за движение машины.
В коде есть MonoBehavior , вездесущий родительский класс для представления компонентов. Большинство невстроенных компонентов будут наследовать от MonoBehavior , который, в свою очередь, наследует от Behavior и Component , соответственно.
- Все объекты, обладающие здоровьем, будь то Player (Игрок) или Enemy (Враг) могут иметь компонент LivingObject , задающий исходное значение здоровья, принимающий урон и приводящий в исполнение смерть, когда объект умирает.
- Кроме того, у игрока может быть компонент ввода, контролирующий сообщаемые ему движения, а у врага может быть аналогичный компонент, реализованный при помощи искусственного интеллекта.
Как вы догадываетесь, компоненты также могут предоставлять и публичные методы. Другие компоненты могут принимать ссылку на данный и вызывать эти публичные методы.
Ресурсы
Ресурсы – это расположенные на диске сущности, из которых состоит игровой проект. К ним относятся сети (модели), текстуры, спрайты, звуки и другие ресурсы.
Когда ваши сцены сериализуются на диск, система представляет их в виде ресурсов, состоящих из игровых объектов внутри них. В следующем разделе мы также рассмотрим, как превратить часто переиспользуемые игровые объекты в ресурс под названием «шаблонные экземпляры» (prefab).

Также ресурсы могут представлять менее «осязаемые» объекты, например, карты контроля ввода, графические настройки, строковые базы данных для интернационализации и многое другое. Также можно создавать собственные типы ресурсов при помощи ScriptableObjects. Вот статья о том, как сохранять такие вещи.
Для проекта, находящегося в разработке, ресурсы – это ключевая информационная составляющая базы кода, наряду с кодом как таковым.
В готовом пакете с игрой будет содержаться большинство ваших ресурсов. Они будут сохранены на диске на том устройстве, где установлена игра.
Шаблонные экземпляры
Игровые объекты, их компоненты и параметры ввода существуют в сцене как отдельные экземпляры. Но что, если объекты определенного класса то и дело повторяются? Такие объекты можно оформить в виде шаблонов, каждый из которых – фактически, объект в виде ресурса.
Шаблоны экземпляров в сцене поддаются локальным модификациям, позволяющим отличать их друг от друга (например, если объект дерево выполнен в виде шаблона, то можно сделать экземпляры деревьев разной высоты). Все экземпляры, выполненные по шаблону, наследуют от него и переопределяют данные шаблона.
Вложенные шаблоны
Начиная с Unity 2018.3, поддерживается вложение шаблонов, чего и следовало ожидать:
- Родительский объект с дочерними объектами, представленными в виде шаблонов, сам может быть представлен в виде шаблона. Внутри родительского шаблона дочерний шаблон допускает собственные модификации. В сцене инстанцируется сразу вся иерархия шаблонов, а поверх нее также могут надстраиваться модификации, специфичные для конкретной сцены.
- Шаблонный экземпляр, находящийся в сцене и снабженный собственными локальными модификациями, может быть сохранен как самостоятельный ресурс «Prefab Variant». Этот вариант представляет собой шаблонный ресурс, наследующий от другого шаблона, поверх которого применены дополнительные модификации.
Сериализация и десериализация
Все ресурсы, сцены и объекты вашего проекта долговременно сохраняются на диске. При редактировании игры эти объекты загружаются в память, а затем сохраняются обратно на диск с помощью системы сериализации, действующей в Unity. При тестовых прогонах игры объекты и сцены, находящиеся в памяти, загружаются при помощи одной и той же системы сериализации. Эта система также соотносит ресурсы, находящиеся в скомпилированном пакете, с загруженными/выгруженными объектами сцены в памяти.
Поток сериализации/десериализации, действующий в движке Unity, загружает в память ресурсы, расположенные на диске (в вашем проекте: для редактирования или тестового прогона игры, либо в самой игре, при загрузке сцены) и отвечает за сохранение состояния отредактированных вами объектов и компонентов обратно в соответствующие сцены и шаблонные экземпляры.
Следовательно, система сериализации также является ключевым элементом работы с редактором Unity. Чтобы MonoBehavior мог принять ввод при конструировании сцены в ходе ее инициализации, эти поля должны быть сериализованы.
Большинство базовых типов Unity, в частности, GameObject , MonoBehavior и ресурсы поддаются сериализации и могут получать исходные значения при создании прямо из редактора Unity. Публичные поля в вашем MonoBehavior сериализуются по умолчанию (если относятся к сериализуемому типу), а приватные поля для этого сначала нужно пометить атрибутом Unity [SerializeField] , и тогда они тоже могут быть сериализованы.
Скриншот игры Chaos Reborn производства Snapshot Games, 2015 год. BY-CC-SA 3.0
Компоненты и моноповедения в Unity
Каждый игровой объект в Unity состоит из компонентов. Любой компонент четко реализует конкретный набор поведений, необходимых для того, чтобы выполнялся GameObject. Почему объект получается таким, каков он есть? Именно благодаря вкладу, который вносят компоненты, из которых этот объект состоит.
На картинках ниже — объект «Warrior». Он показан над окном «Инспектор» в интерфейсе игрового движка Unity. Обратите внимание на проиллюстрированные разделы (Animator, Rigidbody, Collider) – они, как раз таки, и являются компонентами, слагающими этот объект.


Представим, к примеру, что речь идет про автомобиль в игре:
— у единственного «видимого» элемента авто будет компонент Renderer, отрисовывающий машину и, скорее всего, компонент Collider, который задает для авто границы столкновений; — если авто представляет персонажа, то у самого объекта Car возможно наличие Player Input Controller (контроллера ввода от персонажа). Этот контроллер принимает все события, связанные с нажатиями клавиш, а также транслирует их в код, который, в свою очередь, отвечает за движение автомобиля в игре.
Нельзя не сказать, что есть возможность писать большие и сложные компоненты, в которых компонент один в один равен кодируемому объекту (к примеру, компонент player содержит код, который полностью описывает персонажа, а компонент enemy, в свою очередь, полностью кодирует противника). Как правило, принято извлекать логику и дробить ее на небольшие «обтекаемые» кусочки, которые будут соответствовать конкретным признакам. К примеру: • все объекты, которые обладают здоровьем, будь то Player или Enemy, могут иметь компонент LivingObject, который задает исходное значение здоровья, принимает урон и приводит в исполнение смерть, если объект умирает; • у игрока может быть компонент ввода, который контролирует сообщаемые ему движения, а у врага — аналогичный компонент, реализованный посредством искусственного интеллекта.
На протяжении своего жизненного цикла компоненты получают разные обратные вызовы, которые в среде Unity называются Сообщениями. В частности, к Сообщениям относятся: — OnEnable/OnDisable, — Start, — OnDestroy, — Update и прочие.
Если объект реализует метод Update() , то данный метод будет вызываться Unity в каждом кадре игрового цикла, и происходить это будет до тех пор, пока объект является активным, а заданный компонент действует. Эти методы можно пометить private — в таком случае игровой движок Unity все равно будет вызывать их.
Наверное, вы уже догадались, что компоненты могут предоставлять и публичные методы. В таком случае другие компоненты могут принимать ссылку на данный компонент и вызывать эти публичные методы.
Остается добавить, что в коде есть MonoBehavior — вездесущий родительский класс, предназначенный для представления компонентов. Большая часть невстроенных компонентов будут наследовать от MonoBehavior, а он уже, в свою очередь, будет наследовать от Behavior и Component, соответственно.