Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Unity_в_действии_Джозеф_Хокинг_Рус.pdf
Скачиваний:
83
Добавлен:
21.06.2022
Размер:
26.33 Mб
Скачать

162      Глава 7. Игра от третьего лица: перемещение и анимация игрока

Скопируйте проект из главы 2, чтобы воспользоваться им как основой. Также можно открыть новый проект Unity (убедитесь, что вы создаете проект 3D, а не 2D, как в главе 5) и скопировать в него файл сцены из главы 2. Кроме того, вам понадобится папка scratch из материалов к данной главе. Именно в ней находится модель персонажа.

ПРИМЕЧАНИЕ  Мы собираемся разрабатывать новый проект в интерьерах сцены из главы 2. Стены и источники света останутся теми же, замене подлежат только персонаж и все сценарии. Если вы хотите заранее иметь новые варианты для сравнения, скачайте примеры файлов к данной главе.

Если вы начали с готового проекта из главы 2 (я имею в виду демонстрационный ролик, а не более позднюю версию), удалите все, что нам не нужно. Первым делом разорвите связь камеры с игроком на вкладке Hierarchy (это делается простым перетаскиванием). Затем удалите объект player; если бы камера оставалась его дочерним объектом, она при этом тоже исчезла бы, в то время как нам нужно избавиться только от выступающей в роли игрока капсулы, сохранив камеру. Если же вы случайно удалили камеру, создайте новую, выбрав в меню GameObject команду Camera.

Заодно удалите все сценарии (для этого потребуется избавить камеру от компонента script и удалить все файлы сценариев на вкладке Project). В сцене должны остаться только стены, пол и источники света.

7.1. Корректировка положения камеры

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

Д а а

Д а а

Рис. 7.3. Сравнительный вид сцены от первого и от третьего лица

Сцена уже полностью готова, осталось поместить в нее модель персонажа.

7.1. Корректировка положения камеры      163

7.1.1. Импорт персонажа

Входящая в число материалов к данной главе папка scratch содержит как саму модель, так и текстуру; как вы узнали в главе 4, файл FBX — это модель, а файл TGA — это текстура. Импортируйте в проект файл FBX, перетащив его на вкладку Project или щелкнув на этой вкладке правой кнопкой мыши и выбрав в открывшемся меню команду Import New Asset. Теперь обратите внимание на панель Inspector, так как нам нужно скорректировать параметры импорта модели. Редактированием анимации вы зай­ метесь чуть позже, а пока ограничимся парой параметров на вкладке Model. Первым делом присвойте параметру Scale Factor значение 10 (частично компенсируя слишком маленькое значение параметра File Scale), чтобы получить модель корректного размера.

Чуть ниже вы найдете параметр Normals (рис. 7.4). Он контролирует вид света и теней на модели, используя для этого такое математическое понятие, как нормали.

За а а а Scale Factor,

а а

а а File Scale. О ••

• • • Unity •

а€а ‚ а ,

‚ а •а €а а

У а„ а

а• •• •

Рис. 7.4. Параметры импорта для модели персонажа

ОПРЕДЕЛЕНИЕ  Нормалями (normals) называются перпендикулярные полигонам векторы направления, указывающие лицевую сторону полигонов. Именно это направление используется для вычисления освещенности.

По умолчанию параметр Normals имеет значение Import, что означает использование нормалей, задаваемых геометрией импортированной сетки. Однако нормали нашей модели определены некорректно, что дало бы странную реакцию на источники света. Поэтому мы присвоим данному параметру значение Calculate, заставив Unity вычислять вектор для лицевой стороны каждого полигона.

Завершив редактирование этих двух параметров, щелкните на кнопке Apply на панели Inspector. Затем импортируйте в проект файл TGA и сделайте полученное изображение текстурой материала. Для этого выделите материал player в папке Materials и на панели Inspector перетащите изображение текстуры на ячейку Albedo. Цвет модели после этого практически не изменится (эта текстура по большей части имеет белый цвет), но имеющиеся на текстуре тени улучшат внешний вид модели.

После назначения текстуры перетащите модель персонажа с вкладки Project в сцену. Введите в поля Position значения 0, 1.1, 0, чтобы персонаж оказался стоящим на полу в центре помещения. Итак, мы сделали первый шаг к созданию игры от третьего лица!

164      Глава 7. Игра от третьего лица: перемещение и анимация игрока

ПРИМЕЧАНИЕ  Руки импортированного персонажа вытянуты в стороны, хотя естественнее было бы опустить их вниз. Это так называемая T-образная поза, по умолчанию придаваемая всем анимируемым персонажам.

7.1.2. Добавление в сцену теней

Перед тем как двинуться дальше, хотелось бы осветить такой аспект, как отбрасываемая персонажем тень. Мы считаем появление теней само собой разумеющимся, но в виртуальном мире свои законы. К счастью, Unity в состоянии позаботиться о таких вещах, и источник света, по умолчанию присутствующий в любой новой сцене, приводит к формированию теней. Выделите на вкладке Hierarchy строку Directional Light и обратите внимание на параметр Shadow Type на панели Inspector. Он, как показано на рис. 7.5, имеет значение Soft Shadows (мягкие тени), при этом среди доступных значений есть и вариант No Shadows (без теней).

В а а

а

Рис. 7.5. Сцена до и после включения режима формирования теней от направленного источника света

Это все, что требуется для настройки теней в рамках данного проекта, но, разумеется, в целом создание теней в играх представляет собой куда более сложный процесс. Расчет теней в сцене является крайне затратной по времени операцией, поэтому для получения нужного эффекта зачастую идут на хитрости и различными способами имитируют нужные детали. Тени от персонажа относятся к так называемым теням, визуализируемым в реальном времени (real-time shadow), так как они вычисляются

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

всценах накладывают ограничения как на вид теней, так и на количество источников света, приводящих к их формированию. Обратите внимание, что в нашей сцене тени формирует только направленный осветитель.

Другим распространенным приемом создания теней является применение карт освещения.

ОПРЕДЕЛЕНИЕ  Картами освещения (lightmaps) называются текстуры, которые назначаются геометрии игровых уровней и в которых «запечено» изображение теней.

7.1. Корректировка положения камеры      165

ОПРЕДЕЛЕНИЕ  Рисование теней на текстуре модели называется запеканием теней (baking the shadows).

Так как получаемые изображения генерируются заранее (а не во время игры), они могут быть крайне детализированными и реалистичными. Разумеется, они полностью статичны и поэтому используются с неподвижной геометрией игрового уровня, но совершенно неприменимы к динамическим объектам, например персонажам. Карты освещения генерируются автоматически. Компьютер вычисляет, как имеющиеся в сцене источники света будут освещать уровень, оставляя в углах небольшое затемнение. Система визуализации карт освещения в Unity называется Enlighten. Используйте это название как ключевое поисковое слово в справочниках по Unity.

Делать выбор между визуализацией теней в реальном времени и картами освещения не нужно. Свойство источника света Culling Mask позволяет воспользоваться визуализацией в реальном времени только для определенных объектов, сымитировав детализированные тени от остальных объектов сцены с помощью карт освещения. Кроме того, хотя основной персонаж обычно в обязательном порядке отбрасывает тень, далеко не всегда нужно, чтобы на нем формировались тени от окружающих объектов. Поэтому для всех сеточных объектов можно включить функции отбрасывания и восприятия теней, как показано на рис. 7.6.

С а

С а а

а

Рис. 7.6. Параметры Cast Shadows и Receive Shadows на панели Inspector

ОПРЕДЕЛЕНИЕ  Термин «отбор» (culling) в общем случае означает исключение ненужных вещей. В посвященных компьютерной графике статьях он появляется в разных контекстах, в данном же случае свойство Culling mask определяет набор объектов, которые не будут отбрасывать тени.

Итак, вы познакомились с основами добавления теней в сцены. Освещение сцен и формирование теней — сама по себе обширная тема (в книгах, посвященных редактированию игровых уровней, ей зачастую посвящается не одна глава), но мы ограничимся визуализацией теней в реальном времени от одного источника света. И зай­ мемся настройкой камеры.

7.1.3. Облет камеры вокруг персонажа

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

166      Глава 7. Игра от третьего лица: перемещение и анимация игрока

Первым делом выберите положение камеры относительно персонажа. Я ввел в поля positionзначения 0, 3.5, –3.75, расположив камеру чуть выше персонажа и за его спиной (в полях rotation при этом должны быть значения 0, 0, 0). После этого нужно создать­ сценарий OrbitCamera (его код показан в следующем листинге). Присоедините сценарий к камере в виде нового компонента, а затем перетащите персонажа player на ячейку Target. Запустите сцену, чтобы посмотреть, как работает код камеры.

Листинг 7.1. Сценарий вращения нацеленной на объект камеры вокруг объекта

using UnityEngine;

using System.Collections;

public class OrbitCamera : MonoBehaviour {

Сериализованная ссылка

 

[SerializeField] private Transform target; ¬

на объект, вокруг которого

 

 

 

производится облет.

 

public float rotSpeed = 1.5f;

 

 

private float _rotY;

 

 

private Vector3 _offset;

 

 

void Start() {

 

 

 

_rotY = transform.eulerAngles.y;

 

 

 

_offset = target.position - transform.position; ¬ Сохранение начального смещения

}

 

между камерой и целью.

 

 

 

void LateUpdate() {

 

 

 

float horInput = Input.GetAxis("Horizontal");

 

 

if (horInput != 0) { ¬ Медленный поворот камеры при помощи клавиш со стрелками…

 

_rotY += horInput * rotSpeed;

 

 

 

} else {

 

 

 

_rotY += Input.GetAxis("Mouse X") * rotSpeed * 3; ¬ или быстрый поворот с помощью мыши.

 

}

 

 

 

Quaternion rotation = Quaternion.Euler(0, _rotY, 0);

Поддерживаем начальное

 

transform.position = target.position - (rotation * _offset); ¬

смещение, сдвигаемое

 

transform.LookAt(target); ¬ Камера всегда направлена на

в соответствии с поворотом

}

камеры.

цель, где бы относительно этой

 

}

цели она ни располагалась.

 

 

 

 

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

идать возможность связать с ней объект, изображающий персонаж. Следующая пара переменных связана с углами поворота и используется тем же способом, что и в коде управления камерой в главе 2. Еще код содержит объявление переменной _offset; в методе Start() ей присваивается разница в положении камеры и целевого объекта. Это позволяет в процессе выполнения кода сценария сохранять относительное положение камеры. Другими словами, камера все время будет оставаться на одном

итом же расстоянии от целевого объекта, в какую бы сторону она ни поворачивалась. Остальная часть кода помещена в метод LateUpdate().

7.1. Корректировка положения камеры      167

СОВЕТ  Метод LateUpdate() также относится к классу MonoBehaviour и подобно методу Update() запускается в каждом кадре. Как понятно из его имени, метод LateUpdate() вызывается для всех объектов после того, как с ними поработал метод Update(). Таким способом мы обеспечиваем обновление камеры только после перемещения целевого объекта.

Первым делом код увеличивает угол поворота в зависимости от элементов управления вводом. Так как рассматриваются элементы двух типов: клавиши с горизонтальными стрелками и горизонтальные перемещения указателя мыши, — для переключения между ними служит условная инструкция. Код проверяет нажатие клавиш со стрелками; в случае положительного результата проверки применяется этот тип ввода, в противном случае проверяется указатель мыши. Независимая проверка двух вариантов ввода позволяет в каждом случае задать собственную скорость вращения.

Затем код задает положение камеры на основе положения целевого объекта и угла поворота. Строка transform.position, скорее всего, является самым непонятным фрагментом этого кода, так как содержит важные математические вычисления, с которыми вы пока не сталкивались. Умножение вектора position на кватернион (обратите внимание, что угол поворота преобразован в кватернион методом Quaternion.Euler) дает нам новое положение, смещенное в соответствии с углом поворота. Этот новый вектор положения затем добавляется к смещению от положения персонажа, что дает нам положение камеры. Этапы и подробный механизм вычислений этой компактной строки кода иллюстрирует рис. 7.7.

У а а а

а

transform.position = target.position - (rotation * _offset);

За а , а

а • • а

1. О а ,

2. У а

3. В а • а,

 

а а

 

а а

а а

• а

П

И •

а

П • а

Рис. 7.7. Этапы вычисления положения камеры