Уроки Uniti3d - Игровой персонаж

Добавленный на остров, в предыдущей главе, игровой персонаж представлен в виде префаба (prefab – объект шаблона) предоставленный Unity Technologies в пакете Standard Assets, этот объект является примером игрового персонажа от первого лица. Но как добились такого эффекта?
В этой главе мы разберемся с этим, мы рассмотрим, как работает каждый из компонентов и что они делают вместе, чтобы создать наш игровой персонаж. Мы начнем работу со скриптами.

Мы рассмотрим следующие вопросы, чтобы помочь вам понять, как с помощью объединение нескольких объектов и компонентов можно создать полностью рабочего персонажа:
• Теги (Tags), слои (layers) и префабы (prefabs) в Inspector-е;
• Родительско-дочерние (parent-child) отношение объектов;
• основы JavaScript;
• Код передвижения игрока;
• Настойка public переменных в Inspector-е ;
• Использование камеры для создания Viewpoint (точка обзора).

Работа с инспектором свойств.

Давайте начнем с функций Inspector (инспектора свойств), которые являются общими для всех объектов.
В шапке (верхняя часть) Inspector-а, вы увидите имя выбранного объекта, с иконкой игрового объекта (game object) или префаба (prefab) (красно-зелоно-синий куб или голубой куб соответственно), а так же checkbox (переключатель) для временного или постоянного отключения объекта.
Например, для недавно созданного игрового объекта (не от префаба) Directional light, шапка инспектора свойств (Inspector) выглядит так:
Фото
Здесь вы можете видеть красно-зелоно-синию иконку, которая представляет собой стандартный игровой объект (game object). Стоит также отметить, что поле имени объекта

может быть использовано для переименования объекта, просто выберете это поле и введите/отредактируйте имя.
Чуть ниже имени и иконки вы увидите два параметра – Tag (Тег) и Layer (Слой).

Теги.

Tags - ключевые слова, которые могут быть назначены на игровой объект. Назначив тег, вы можете использовать выбранное слово или фразу, чтобы обратиться к игровому объекту (или объектам), на который он назначен, из скрипта (один тег может использоваться много раз).
Добавление тегов к игровому объекту происходит в два этапа - сначала, ваш тег должен быть добавлен к списку в Tag Manager, , а затем применен к выбранному объекту.
Что бы помочь вам освоиться с тегами, добавим ваш первый тег к объекту Directional light. Для этого выберете этот объект в окне Hierarchy, и кликните на выпадающее меню Tag, которое на данный момент имеет значение Untagged.
Вы увидите список существующих тегов. Вы можете выбрать один из существующих или создать новый тег. Внизу меню выберите Add Tag, чтобы добавить теги к списку в Tag Manager.
Фото
Окно Inspector-а переключится на отображение Tag Manager.
Tag Manager показывает как Tags (теги), так и Layers (слои). Чтобы добавить новый тег, вы должны нажать на серую стрелку слева от Tags, вы увидите поля Size и Element.
Теперь вы можете печатать справа от Element 0.
Введите имя Sunlight (замете, вы можете придумать любое имя) и нажмите Enter для подтверждения. Обратите внимание, что после того как вы нажмете Enter, значение поля Size увеличится на один и появится новое поле Element – не стоит этого пугаться, т.к. это необходимо для добавления следующего тега.
Фото

Параметр Size определяет количество созданных тегов. Unity использует систему Size и Element для различных меню, и вы столкнетесь с этим в дальнейшем, поскольку мы продолжаем работать с Inspector-ом.
Вы добавили тег к списку. Тем не менее, он еще не добавлен к объекту Directional light.
Поэтому заново выберем наш источник света в окне Hierarchy, и повторно нажмем на Untagged возле параметра Tag в инспекторе свойств. Вы увидите вновь созданный тег Sunlight внизу списка тегов. Что бы применить этот тег, просто выберете его и выпадающего меню, как показано на рисунке:
Фото

Слои.

Layers (слои) - дополнительный способ группирования объектов, чтобы применять к ним особые правила. В основном они используются для заданий правил рендеринга для света и камер. Так же, они могут быть использованы в физике, для техники называемой Ray casting, чтобы выборочно игнорировать определенные объекты.

Слои (Layers) создаются таким же образом, как и теги (Tags), и также доступны в Tag Manager, они находятся ниже списка тегов.

Префабы и инспектор свойств.

Если выбрать префаб (prefab) в окне Hierarchy, то вы увидите дополнительные параметры, как показано на рисунке:
Фото
Под полями Tag и Layer вы можете увидеть три дополнительных кнопки, для взаимодействия с изначальным (originating) префабом.
• Select: Определяет местонахождение и выделяет префаб, которому принадлежит этот объект в окне проекта (Project).
• Revert: Возвращает настройки компонентов объекта к настройкам изначального префаба находящегося в окне проекта.
• Apply: Изменяет настройки префаба (prefab) на настройки выборного экземпляра префаба. При этом обновляются любые другие копии этого префаба, в настоящее время, находящиеся на активной сцене.
Теперь, когда вы ознакомлены с дополнительными настройками в Inspector-е, давайте начнем изучение игрового персонажа (player character).

Deconstructing the First Person Controller object.

Давайте начнем с рассмотрения объектов, из которых состоит First Person Controller (FPC) (управление от первого лица), прежде, чем мы изучим компоненты, которые заставляют его работать.
Кликнете на серой стрелочке слева от First Person Controller в окне Hierarchy, чтобы показать вложенные объекты. Когда объекты вложены таким образом, мы говорим, что есть родительско-дочерние отношения (parent-child relationship). В нашем случае, First Person Controller родительский объект, а Graphics и Main Camera дочерни объекты. В Hierarchy, дочерние объекты смещены, чтобы выделить их родителей, как показано на следующем рисунке:
Фото

Проблема отцов и детей.

Рассматривая вложенные или дочерние объекты, следует запомнить несколько важных правил.
Позиция (position) и поворот (rotation) дочернего объекта рассматриваются относительно родительского объекта. Это называется, локальной позицией (local position) и локальным поворотом (local rotation). Например, предположим, что ваш родительский объект находиться в точке (500, 35, 500) мировой системы координат (world coordinates), но при выборе дочернего объекта, вы заметите, что его позиция (0,0,0), но при этом он находиться в той же точке, что и родитель. Это и есть то, что подразумевается под ‘относительно’ - помещая дочерний объект в (0,0,0), мы говорим ему находиться в начале координат его родителя или относительно позиции родителя.
Выбрав в Hierarchy дочерний объект Graphics объекта FPC, вы увидите, что его позиция (0,0,0), хотя он находится в той же точке что и FPC.
Следует так же знать, что, перемещая родительский объект, дочерние объекты будут соответственно менять и свое положение, для сохранения локальных позиции и поворота.

Объекты First Person Controller.

Три части этого объекта следующие:
1. First Person Controller: Объект FPC или родитель группы, к которому применен основной код (main scripting) и collider, которые управляют его поведением. К этому объекту прикреплены два скрипта – первый для передвижения с помощью клавиатуры, а второй позволяет вращения при перемещении мыши влево и вправо.
2. Graphics: Примитив Capsule (см. рисунок ниже), который позволяет вам, как разработчику, видеть куда вы поместили FPC.
3. Main Camera: Находиться на уровне глаз игрока. Main Camera обеспечивает наличие viewpoint (точки обзора) и имеет прикрепленный скрипт, который позволяет нам смотреть вверх и вниз.
Фото

Принимая во внимание родительско-дочерние отношения, мы можем сказать, что когда объект FPC двигается или вращается, Graphics и Main Camera будут следовать за ним.

Объект 1: First Person Controller (родитель).

Выберете First Person Controller в окне Hierarchy и посмотрите на его компоненты в Inspector-е.
Фото
Как показано на рисунке, вы увидите четыре компонента родительского объекта FPC — Transform, FPSWalker (Script), Character Controller и Mouse Look (Script).

Transform.

Как все игровые объекты. FPC имеет компонент Transform, который отображает и позволяет менять позицию (position), поворот (rotation) и масштаб (scale) объекта.

FPSWalker (Script).

Это скрипт, написанный на JavaScript, отвечает за перемещение персонажа вперед и назад, используя vertical axis keys (клавиши вертикальной оси) (стрелка вверх/стрелка вниз или W/S) и из стороны в сторону (игровой термин – стрейф), используя horizontal axis keys (клавиши горизонтальной оси) (стрелка влево/стрелка вправо или A/D), а так же прыгать, используя клавишу jump, по умолчанию это пробел (Space bar).
Скрипт имеет три public переменные (public member variables) отображаемых в инспекторе свойств (Inspector), что позволяет настроить скрипт, не открывая его. Это Speed, Jump Speed и Gravity.
Хотя физический движок Unity позволяет управлять объектом с компонентом Rigidbody, но есть одно 'но'. Наш объект должен иметь собственный вес (силу тяжести), определенный в скрипте - эта переменная позволяет нам увеличивать свое действие, в результате заставляя нас падать быстрее.
У любого компонента скрипта есть первый параметр Script (и единственный, пока не назначен скрипт). Этот параметр позволяет вам переназначить скрипт, без необходимости, удалить, а потом создать, новый компонент. При смене скрипта, одноименные параметры или одинаковые public переменные сохраняют свои значения в Inspector-е.

Character Controller.

Этот объект выступает в качестве Collider-а (компонент обеспечивает объекту физическое присутствие, т.е. позволяет взаимодействовать с другими объектами), он специально разработан для обеспечения движения персонажа и управления им в мире. И имеет следующие параметры:
• Height: Высота персонажа, которая определяет, насколько высокой будет капсула collider (capsule-shaped collider) персонажа.
• Radius: Какой ширины будет капсула collider – по умолчанию равен радиусу дочернего объекта Graphics. Однако, если вы хотите, чтобы ваш персонаж был шире, либо для ограничения движения, либо для обнаружения столкновений на большей площади, то можно увеличить значение этого параметра.
• Slope Limit: Определяет угол наклона поверхности доступной для движения персонажа. Если угол наклона поверхности будет больше, чем указанно в этом параметре, персонаж не сможет взобраться по ней.
• Step Offset: Определяет, как высоко от пола персонаж может подняться – применяется для определения возможности персонажа взойти по лестнице, подняться на бордюр и т.п.

• Skin Width: Поскольку персонаж сталкивается с другими игровыми объектами на сцене, часто на большой скорости, этот параметр определяет, как глубоко другие collider-ы могут пересечься с collider-ом персонажа без реакции. Специально разработано, чтобы уменьшать конфликты с объектами, результатом которых может быть дрожание или застревание персонажа в стенах. Это случается когда два collider–а быстро сталкиваются и игровой движок не успевает отреагировать на это столкновение. Unity Technologies рекомендует установить Skin Width равным 10% от радиуса (Radius).
• Min Move Distance: Это самое маленькое расстояние, на которое ваш персонаж может быть перемещен. Обычно устанавливается в ноль, т.к. большее значение означает, что ваш персонаж не сможет двигаться, пока его перемещение не превысит это значение. Как правило, Min Move Distance используется только для снижения дрожания, но в большинстве случаев остается равным 0.
• Center: Vector3 (x, y, z значения). Позволяет смещать collider персонажа относительно его локального центра. Обычно равно нулю, чаще используются для персонажа от третьего лица (third person character), который будет иметь более сложную форму, чем простая капсула.
Character Controller представлен на сцене как зеленый каркас в форме капсулы, т.е. он имеет почти такой же внешний вид как и другие collider-ы в Unity. Я временно отключил рендер дочернего объекта Graphics, что бы вы могли увидеть, как выглядит Character Controller:
Фото

Mouse Look (Script).

Написан на C#, скрипт отвечает за поворот персонажа, когда мы перемещаем мышь. Этот скрипт имеет следующие public переменные:
• Axes: В данном случае установлен в MouseX. Эта переменная может принять значениеMouseX, MouseY или MouseXAndY. Для этого экземпляра скрипта Mouse Look (мы имеем еще один экземпляр этого скрипта добавленный к объекту Main Camera, у которого этот параметр равенMouseY), мы установили Axes в MouseX, так как это разрешает движение мыши влево и вправо, для поворота нашего персонажа – следовательно, и поворот камеры, т.к. Main Camera дочерний объект.
Вы спросите – почему же в экземпляре скрипта Mouse Look для Main Camera мы сразу не установим этот параметр в MouseXAndY? Проблема в том, что хотя мы и смогли бы вращать камеру вдоль двух осей, персонаж бы не поворачивался, так как эти изменения локальные и не распространяются на родительский объект (FPC).
• Sensitivity X/Sensitivity Y: В данном случае, этот параметр будет контролировать, насколько движение мыши влево/вправо влияет на поворот персонажа. Если бы параметр Axes был равен MouseY, то можно было бы определить чувствительность поворота к движению мышью вверх/вниз. Чем выше значение, тем быстрее поворот.
• Minimum X/Maximum X: Позволяет ограничить угол поворота влево/вправо. В данном случае, установлен в -360 и 360 соответственно, что позволяет игроку совершать полный поворот в любом направлении вдоль оси Х.
• Minimum Y/Maximum Y: Позволяет ограничить угол поворота вверх/вниз.

Объект 2: Graphic.

Т.к. у нас игра от первого лица, игрок никогда не увидит своего тела, в форме капсулы. В данном случае его визуальное представление предназначено для разработчиков, что бы было проще позиционировать и находить FPC в окне сцены (Scene window). Часто, разработчики выключат рендеринг меша, путем отключая компонент Mesh Renderer в Inspector-е.
Выберете объект Graphics в окне Hierarchy, и взгляните на его компоненты в инспекторе свойств (Inspector).
Фото
Как и у любого другого объекта, у Graphics есть компонент Transform, позиция объекта (0,0,0), это означает, что он находиться в центре родительского объекта First Person Controller. Поскольку единственная цель этого объекта состоит в том, чтобы представить нашего игрока визуально, у него есть два ключевых компонента, которые делают его видимым - Mesh Filter и Mesh Renderer. Но что делают эти два компонента?

Mesh filter.

В данном случае, он называется Poly Surface 2. Именем компонентаMesh Filter, обычно, является имя объекта, который он представляет. Поэтому, когда вы внедряете внешне созданные модели, можно заметить, что каждый компонентMesh Filter назван в честь каждой части модели.
Mesh Filter компонент, содержащий меш.

Mesh renderer.

Mesh Renderer необходим для отображения поверхности меша 3D объекта. Он также отвечает за a) как меш реагирует на освещение и b) материалы, используемые на поверхности, чтобы показать цвета или текстуры.
Mesh Renderer имеет следующие параметры:
• Cast Shadows: Будет ли объект отбрасывать тень на другие объекты при воздействии на него источника света (доступно только в Unity Pro).
• Receive Shadows: Будет ли этот объект отображать тени от других объектов (доступно только в Unity Pro).
В нашем случае, оба этих параметра отключены т.к. во-первых, тень от капсулы будет смотреться довольно странно, во-вторых, т.к. игрок не видит капсулы, отображать на ней тени излишне.
• Materials: Эта область использует систему Size/Element, подобное вы видели в Tag Manager. Она позволяет указать один или несколько материалов.
Наш объект Graphics не нуждается ни в настройки цвета, ни в назначении материала.
Однако этот вопрос мы рассмотрим в следующих главах.

Объект 3: Main Camera.

Main Camera это ваша область просмотра (viewport). В префабе First Person Controller, Main Camera расположена на уровне глаз (наверху капсулы Graphics) и управляется скриптами, позволяя игроку перемещать весь родительский объект и камеру независимо.
Таким образом, игрок может ходить и осматриваться одновременно.
Обычно, игровой объект камеры состоит из трех основных компонентов - Camera, GUILayer и Flare Layer, в дополнение к стандартному компоненту Transform. Камеры так же имею компонент Audio Listener, для восприятия звука, но обычно этот компонент удаляется, за исключением последнего, т.к. Unity требует, что бы на сцене находился только один слушатель (Audio Listener).
В нашем случае, у нашей камеры есть еще один компонент Mouse Look (Script), который вращает камеру, основываясь на движении мыши.

Camera.

Обычно ему сопутствуют компоненты GUILayer и Flare Layer, компонент Camera основной компонент, отвечающий за создания viewpoint. . Для того чтобы понять, каким образом компонент Camera формирует viewpoint (точку обзора), мы рассмотрим его параметры.
Фото
• Clear Flags: Обычно этот параметр установлен в его значение по умолчанию, Skybox, чтобы позволить камере рендерить материал skybox-а, в настоящее время примененный к сцене. Но чтобы позволить вам, разработчику, управлять использованием нескольких камер, параметр Clear Flags нужен, чтобы определяет, какие части экрана не будут отрисовываться. Каждая камера хранит информацию о цветах и глубинах, когда она рендерит свое отображение. Участки экрана, в которые не происходит отрисовка - пусты, и по умолчанию будут отображать skybox. Когда Вы используете несколько камер, каждая из них сохраняет свою собственную информацию о глубинах и цвете в буферах, собирая все больше данных, когда каждая из камер производит рендер. Так как каждая из камер на сцене рендерит собственное отображение, Вы можете установить значения Clear Flags, чтобы очищать различные наборы информации из буферов. Это делается выбором одной из четырех опций:
Skybox - Все пустые участки экрана будут отображать skybox текущей камеры.
Если у текущей камеры нет skybox-а, будет использоваться стандартный skybox, указанный в Render Settings (Edit→Render Settings). Если и его нет, то используется фоновый цвет (Background Color).
Solid Color - Все пустые участки экрана будут закрашены фоновым цветом (Background Color).
Depth Only – Если Вам захочется отрисовать оружие игрока, чтобы не было клиппинга с объектами окружающей среды, то одна камера ставится на глубину 0 для отрисовки окружающей среды, и другую камеру на глубину 1, чтобы отдельноотрисовать оружие. У камеры для оружия Clear Flags должен быть установлен в Depth Only. Это сохранит графическое отображение окружающей среды на экране, но сбросит всю информацию о том, где каждый из объектов расположен в трехмерном пространстве. Когда отрисовывается оружие, его непрозрачные части полностью перекроют все нарисованное, вне зависимости от того, насколько близко оружие к стене. Don't Clear - Этот режим не очищает ни буфер цвета, ни буфер глубины. В результате каждый кадр отрисовывается поверх следующего, образуя эффект смазывания. Обычно это не используется в играх, и скорее всего лучше всего для использования вместе с пользовательским шейдером.

• Back Ground Color: Фоновый цвет применятся к тем частям экрана, которые остались пусты после рендера всех объектов. Работает только, если нет skybox-а.
• Normalized View Port Rect: Этот параметр позволяет вам изменить размер и позицию camera view (вид из камеры). Измерение идёт в координатах экрана, каждая координата находится в диапазоне 0-1. Обычно, устанавливается во весь экран, как и в нашем случае с Main Camera, прикрепленной к игроку. Если X и Y координаты установленные в 0, то наш вид из камеры (camera view) начинается в левом нижнем углу экрана. Width и Height установленные в 1, обозначают, что вид их камеры имеет размер экрана. Вы увидите эту систему в других 2D элементах, с которыми вы будите работать в Unity, например, графический интерфейс пользователя (GUI - graphical user interface).

Система этих параметров, дает возможность использовать несколько камер в играх, например, в гонках, создать небольшое окно заднего вида, или разделить экран на две части, для совместного прохождения игры двумя игроками.
• Near clip plane/Far clip plane: Сlip planes (ограничивающие плоскости) определяют расстояния, на протяжении которого отрисовывается игровой мир - near plane, расстояние, после которого камерой начинают отрисовываться объекты (всё, что ближе, не отрисовывается), far plane, расстояние, до которого камерой отрисовываются объекты (всё, что дальше, не отрисовывается).
Фото
• Field of view: Этот параметр определяет ширину области просмотра камеры (camera viewport) в градусах. Этот угол установлен в значение 60 в нашем объекте Main Camera, т.к. это значение наиболее эффективно имитирует вид из глаз человека.
• Orthographic и Orthographic size: Установка флажка включение ортографического вид, вид противоположный 3D виду (перспективному виду).
• Depth: Параметр Depth (глубина) используется, когда задействовано несколько камер. Имея несколько камер, переключение между которыми происходит из скрипта, параметр Depth позволяет указать их приоритетный порядок, то есть камера с более высоким значением глубины выполнит рендер перед камерой с меньшим значением глубины.
• Culling Mask: Этот параметра работает со слоями (Layers) Unity, о которых шла речь выше. Размещая различные элементы игры в определенном слое, вы можете отменить рендер этого слоя (а значит и принадлежащих ему объектов), сняв соответствующий флажок в выпадающем меню Culling Mask. В нашем случае Main Camera визуализирует все слои.

• Render Target (доступно только в Unity Pro): Ссылка на текстуру, которая будет содержать выходное изображение камеры. Одна и та же камера не может рендерить в текстуру и на экран одновременно.

GUILayer и Flare Layer.

Эти два компонента не имеют никаких параметров, но позволяют выполнять дополнительные визуальные элементы/эффекты. GUILayer позволяет рендер 2D элементов, таких как меню и HUD (Head-Up Display). Flare Layer позволяет рендер световых эффектов, например, эффект flare(блеск/сияние) источника света Directional light, который мы реализовали в Главе 2.

Mouse Look (Script).

Это второе применение компонента Mouse Look (Script) – первый мы видели у родительского объекта First Person Controller. Однако, в данном случае параметр Axes установлен в значение MouseY, что позволяет смотреть вверх и вниз. В сочетании со скриптом родительского объекта мы получаем возможность свободно оглядываться во всех направлениях, с помощью мыши.

Audio Listener.

Audio Listener (слушатель) – это наши уши, позволяющие нам слышать audio sources (источники звука). См. Глава 2. Шаг 8 — Что это за звук?