- •Предисловие
- •Введение
- •Благодарности
- •О книге
- •Перспективы
- •Условные обозначения, требования и доступные для скачивания данные
- •Автор в Интернете
- •Об авторе
- •Глава 1. Знакомство с Unity
- •1.1. Достоинства Unity
- •1.1.1. Сильные стороны и преимущества Unity
- •1.1.2. Недостатки, о которых нужно знать
- •1.1.3. Примеры игр на основе Unity
- •1.2. Как работать с Unity
- •1.2.1. Вкладка Scene, вкладка Game и панель инструментов
- •1.2.2. Работа с мышью и клавиатурой
- •1.2.3. Вкладка Hierarchy и панель Inspector
- •1.2.4. Вкладки Project и Console
- •1.3. Готовимся программировать в Unity
- •1.3.1. Запуск кода в Unity: компоненты сценария
- •1.3.2. Программа MonoDevelop — межплатформенная среда разработки
- •1.4. Заключение
- •Глава 2. Создание 3D-ролика
- •2.1. Подготовка…
- •2.1.1. Планирование проекта
- •2.1.2. Трехмерное координатное пространство
- •2.2. Начало проекта: размещение объектов
- •2.2.1. Декорации: пол, внешние и внутренние стены
- •2.2.2. Источники света и камеры
- •2.2.3. Коллайдер и точка наблюдения игрока
- •2.3. Двигаем объекты: сценарий, активирующий преобразования
- •2.3.1. Схема программирования движения
- •2.3.2. Написание кода
- •2.3.3. Локальные и глобальные координаты
- •2.4. Компонент сценария для осмотра сцены: MouseLook
- •2.4.1. Горизонтальное вращение, следящее за указателем мыши
- •2.4.2. Поворот по вертикали с ограничениями
- •2.4.3. Одновременные горизонтальное и вертикальное вращения
- •2.5. Компонент для клавиатурного ввода
- •2.5.1. Реакция на нажатие клавиш
- •2.5.2. Независимая от скорости работы компьютера скорость перемещений
- •2.5.4. Ходить, а не летать
- •2.6. Заключение
- •3.1. Стрельба путем бросания лучей
- •3.1.1. Что такое бросание лучей?
- •3.1.2. Имитация стрельбы командой ScreenPointToRay
- •3.1.3. Добавление визуальных индикаторов для прицеливания и попаданий
- •3.2. Создаем активные цели
- •3.2.1. Определяем точку попадания
- •3.2.2. Уведомляем цель о попадании
- •3.3. Базовый искусственный интеллект для перемещения по сцене
- •3.3.1. Диаграмма работы базового искусственного интеллекта
- •3.3.2. «Поиск» препятствий методом бросания лучей
- •3.3.3. Слежение за состоянием персонажа
- •3.4.1. Что такое шаблон экземпляров?
- •3.4.2. Создание шаблона врага
- •3.4.3. Экземпляры невидимого компонента SceneController
- •3.5. Стрельба путем создания экземпляров
- •3.5.1. Шаблон снаряда
- •3.5.2. Стрельба и столкновение с целью
- •3.5.3. Повреждение игрока
- •3.6. Заключение
- •Глава 4. Работа с графикой
- •4.1. Основные сведения о графических ресурсах
- •4.2. Создание геометрической модели сцены
- •4.2.1. Назначение геометрической модели
- •4.2.2. Рисуем план уровня
- •4.2.3. Расставляем примитивы в соответствии с планом
- •4.3. Наложение текстур
- •4.3.1. Выбор формата файла
- •4.3.2. Импорт файла изображения
- •4.3.3. Назначение текстуры
- •4.4. Создание неба с помощью текстур
- •4.4.1. Что такое скайбокс?
- •4.4.2. Создание нового материала для скайбокса
- •4.5. Собственные трехмерные модели
- •4.5.1. Выбор формата файла
- •4.5.2. Экспорт и импорт модели
- •4.6. Системы частиц
- •4.6.1. Редактирование параметров эффекта
- •4.6.2. Новая текстура для пламени
- •4.6.3. Присоединение эффектов частиц к трехмерным объектам
- •4.7. Заключение
- •5.1. Подготовка к работе с двухмерной графикой
- •5.1.1. Подготовка проекта
- •5.1.2. Отображение двухмерных изображений (спрайтов)
- •5.1.3. Переключение камеры в режим 2D
- •5.2. Создание карт и превращение их в интерактивные объекты
- •5.2.1. Создание объекта из спрайтов
- •5.2.2. Код ввода с помощью мыши
- •5.2.3. Открытие карты по щелчку
- •5.3. Отображение различных карт
- •5.3.1. Программная загрузка изображений
- •5.3.3. Создание экземпляров карт
- •5.3.4. Тасуем карты
- •5.4. Совпадения и подсчет очков
- •5.4.1. Сохранение и сравнение открытых карт
- •5.4.2. Скрытие несовпадающих карт
- •5.4.3. Текстовое отображение счета
- •5.5. Кнопка Restart
- •5.5.1. Добавление к компоненту UIButton метода SendMessage
- •5.5.2. Вызов метода LoadLevel в сценарии SceneController
- •5.6. Заключение
- •Глава 6. Двухмерный GUI для трехмерной игры
- •6.1. Перед тем как писать код…
- •6.1.1. IMGUI или усовершенствованный 2D-интерфейс?
- •6.1.2. Выбор компоновки
- •6.1.3. Импорт изображений UI
- •6.2. Настройка GUI
- •6.2.1. Холст для интерфейса
- •6.2.2. Кнопки, изображения и текстовые подписи
- •6.2.3. Управление положением элементов UI
- •6.3. Программирование интерактивного UI
- •6.3.1. Программирование невидимого объекта UIController
- •6.3.2. Создание всплывающего окна
- •6.3.3. Задание значений с помощью ползунка и поля ввода
- •6.4. Обновление игры в ответ на события
- •6.4.1. Интегрирование системы сообщений
- •6.4.2. Рассылка и слушание сообщений сцены
- •6.4.3. Рассылка и слушание сообщений проекционного дисплея
- •6.5. Заключение
- •7.1. Корректировка положения камеры
- •7.1.1. Импорт персонажа
- •7.1.2. Добавление в сцену теней
- •7.1.3. Облет камеры вокруг персонажа
- •7.2. Элементы управления движением, связанные с камерой
- •7.2.1. Поворот персонажа лицом в направлении движения
- •7.2.2. Движение вперед в выбранном направлении
- •7.3. Выполнение прыжков
- •7.3.1. Добавление вертикальной скорости и ускорения
- •7.3.2. Распознавание поверхности с учетом краев и склонов
- •7.4. Анимация персонажа
- •7.4.1. Создание анимационных клипов для импортированной модели
- •7.4.2. Создание контроллера для анимационных клипов
- •7.4.3. Код, управляющий контроллером-аниматором
- •7.5. Заключение
- •8.1. Создание дверей и других устройств
- •8.1.1. Открывание и закрывание дверей
- •8.1.2. Проверка расстояния и направления перед открытием двери
- •8.1.3. Управление меняющим цвет монитором
- •8.2. Взаимодействие с объектами путем столкновений
- •8.2.1. Столкновение с препятствиями, обладающими физическими свойствами
- •8.2.2. Управление дверью с помощью триггера
- •8.2.3. Сбор разбросанных по игровому уровню элементов
- •8.3. Управление инвентаризационными данными и состоянием игры
- •8.3.1. Настраиваем диспетчеры игрока и инвентаря
- •8.3.2. Программирование диспетчеров
- •8.3.3. Сохранение инвентаря в виде коллекции: списки и словари
- •8.4. Интерфейс для использования и подготовки элементов
- •8.4.1. Отображение элементов инвентаря в UI
- •8.4.2. Подготовка ключа для открытия двери
- •8.4.3. Восстановление здоровья персонажа
- •8.5. Заключение
- •9.1. Создание натурной сцены
- •9.1.1. Генерирование неба с помощью скайбокса
- •9.1.2. Настройка управляемой кодом атмосферы
- •9.2. Скачивание сводки погоды из Интернета
- •9.2.1. Запрос веб-данных через сопрограмму
- •9.2.2. Парсинг текста в формате XML
- •9.2.3. Парсинг текста в формате JSON
- •9.2.4. Изменение вида сцены на базе данных о погоде
- •9.3. Добавление рекламного щита
- •9.3.1. Загрузка изображений из Интернета
- •9.3.2. Вывод изображения на щите
- •9.3.3. Кэширование скачанного изображения
- •9.4. Отправка данных на веб-сервер
- •9.4.1. Слежение за погодой: отправка запросов POST
- •9.4.2. Серверный код в PHP-сценарии
- •9.5. Заключение
- •Глава 10. Звуковые эффекты и музыка
- •10.1. Импорт звуковых эффектов
- •10.1.1. Поддерживаемые форматы файлов
- •10.1.2. Импорт аудиофайлов
- •10.2. Воспроизведение звуковых эффектов
- •10.2.1. Система воспроизведения: клипы, источник, подписчик
- •10.2.2. Присваивание зацикленного звука
- •10.2.3. Активация звуковых эффектов из кода
- •10.3. Интерфейс управления звуком
- •10.3.1. Настройка центрального диспетчера управления звуком
- •10.3.2. UI для управления громкостью
- •10.3.3. Воспроизведение звуков UI
- •10.4. Фоновая музыка
- •10.4.1. Воспроизведение музыкальных циклов
- •10.4.2. Отдельная регулировка громкости
- •10.4.3. Переход между песнями
- •10.5. Заключение
- •Глава 11. Объединение фрагментов в готовую игру
- •11.1. Построение ролевого боевика изменением назначения проектов
- •11.1.1. Сборка ресурсов и кода из разных проектов
- •11.1.2. Элементы наведения и щелчка
- •11.1.3. Замена старого GUI новым
- •11.2. Разработка общей игровой структуры
- •11.2.1. Управление ходом миссии и набором уровней
- •11.2.2. Завершение уровня
- •11.2.3. Проигрыш уровня
- •11.3. Обработка хода игры
- •11.3.1. Сохранение и загрузка достижений игрока
- •11.3.2. Победа в игре при прохождении всех уровней
- •11.4. Заключение
- •Глава 12. Развертывание игр на устройствах игроков
- •12.1. Создание приложений для настольных компьютеров: Windows, Mac и Linux
- •12.1.1. Построение приложения
- •12.1.2. Настройки проигрывателя: имя и значок приложения
- •12.1.3. Компиляция в зависимости от платформы
- •12.2. Создание игр для Интернета
- •12.2.1. Проигрыватель Unity и HTML5/WebGL
- •12.2.2. Создание файла Unity и тестовой веб-страницы
- •12.2.3. Обмен данными с JavaScript в браузере
- •12.3. Сборки для мобильных устройств: iOS и Android
- •12.3.1. Настройка инструментов сборки
- •12.3.2. Сжатие текстур
- •12.3.3. Разработка подключаемых модулей
- •12.4. Заключение
- •Приложение А. Перемещение по сцене и клавиатурные комбинации
- •А.1. Навигация с помощью мыши
- •А.2. Распространенные клавиатурные комбинации
- •Б.1. Инструменты программирования
- •Б.1.1. Visual Studio
- •Б.1.2. Xcode
- •Б.1.3. Android SDK
- •Б.1.4. SVN, Git или Mercurial
- •Б.2. Приложения для работы с трехмерной графикой
- •Б.2.1. Maya
- •Б.2.3. Blender
- •Б.3. Редакторы двухмерной графики
- •Б.3.1. Photoshop
- •Б.3.2. GIMP
- •Б.3.3. TexturePacker
- •Б.4. Звуковое программное обеспечение
- •Б.4.1. Pro Tools
- •Б.4.2. Audacity
- •Приложение В. Моделирование скамейки в программе Blender
- •В.1. Создание сеточной геометрии
- •В.2. Назначение материала
178 Глава 7. Игра от третьего лица: перемещение и анимация игрока
Данные о столкновении включают в себя свойство normal (еще раз напомню, что нормалью называется вектор, определяющий лицевую сторону полигона), указывающее направление ухода от точки столкновения. Но есть один тонкий момент. Мы хотим, чтобы небольшой импульс в сторону от точки контакта обрабатывался в зависимости от того, в каком направлении двигался персонаж. Если предшествующее движение по горизонтали совершалось в сторону платформы, его следует заменить, чтобы персонаж не продолжал смещаться в некорректном направлении. Если же лицом он был повернут в сторону от края, предшествующее движение по горизонтали нужно добавить, чтобы сохранить толкающий вперед импульс. Направление вектора движения относительно точки столкновения определяется при помощи
скалярного произведения.
ОПРЕДЕЛЕНИЕ Скалярным произведением (dot product) называется математическая операция, выполняемая с двумя векторами. Коротко говоря, результат такого произведения варьируется между –1 и 1, где 1 означает, что вектора смотрят в одном направлении, в то время как –1 указывает на диаметрально противоположные направления. Не следует путать скалярное произведение с векторным произведением — другой математической операцией, часто применяемой к векторам.
Объект Vector3 обладает методом Dot(), вычисляющим скалярное произведение двух векторов. Скалярное произведение вектора движения и нормали плоскости столкновения будет отрицательным, если эти вектора смотрят в разные стороны, и положительным при их одинаковом направлении.
В конце листинга 7.5 появляется новый метод. Ранее мы проверяли нормаль плоскости столкновения, но откуда появлялась информация об этой нормали? Оказывается, о столкновениях с контроллером персонажа сообщалось через функцию обратного вызова OnControllerColliderHit(), предоставляемую классом MonoBehaviour; для программирования реакции на данные о столкновении в каком-либо фрагменте сценария следует сохранить эти данные во внешней переменной. Именно этим занимается наш метод: сохраняет данные о столкновении в переменной _contact, предоставляя нам возможность воспользоваться этими данными в методе Update().
Итак, мы скорректировали поведение персонажа на краях платформ и на наклонной плоскости. Запустите игру и посмотрите, что происходит при сходе с края и при попытке запрыгнуть на крутой склон. Наш демонстрационный ролик почти готов. Персонаж нужным образом перемещается по сцене, осталось только придать ему более естественную позу.
7.4. Анимация персонажа
Кроме более сложной формы, определенной сеточной геометрией, наш антропоморфный персонаж нуждается еще и в анимации. В главе 4 вы узнали, что анимация представляет собой пакет информации, определяющий движение связанного с ним трехмерного объекта. В качестве примера мы рассматривали ходящего по сцене персонажа. Именно эту ситуацию вам сейчас предстоит воспроизвести! Персонажу следует назначить анимацию, которая заставит его руки и ноги двигаться взад и вперед, как показано на рис. 7.11.
7.4. Анимация персонажа 179
Т а а а а ,
а Т-а
Рис. 7.11. Персонаж, двигающийся по сцене в процессе воспроизведения анимации
Хорошей аналогией трехмерной анимации является кукольный театр: трехмерные модели играют роль кукол, аниматор представляет собой кукловода, а анимация — это запись перемещений кукол. Существуют разные способы создания анимации; в большинстве современных игр для персонажей используется техника скелетной анимации.
ОПРЕДЕЛЕНИЕ Скелетной анимацией (skeletal animation) называется процедура связывания с моделью набора костей, которые и осуществляют движение. В процессе перемещения кости двигается также связанная с ней поверхность модели.
Принцип скелетной анимации легко понять интуитивно, представив имитацию скелета персонажа (как показано на рис. 7.12). Но при этом «скелет» является абстракцией, применимой в любой ситуации, в которой вам нужна гибкая и деформирующаяся модель с четко определенной структурой, программирующей ее перемещения (к примеру, представьте извивающееся щупальце осьминога). Сами кости перемещаются как недеформируемые объекты, в то время как окружающая их поверхность модели может сгибаться и менять свою форму.
К ( Unity а) |
В а а |
|
|
|
|
К а ,
а а а••а
а а
•
Рис. 7.12. Скелетная анимация антропоморфного персонажа
Получение результата, показанного на рис. 7.11, включает в себя несколько этапов: для начала мы определяем анимационные клипы в импортированном файле, затем настраиваем контроллер для воспроизведения этих клипов и, наконец, вставляем
180 Глава 7. Игра от третьего лица: перемещение и анимация игрока
этот контроллер в наш код. Анимация персонажа будет воспроизводиться в соответствии с написанными вами сценариями движения.
Разумеется, первое, с чего нужно начать, — это подключить систему анимации. Выделите модель персонажа на вкладке Project и на панели Inspector перейдите на вкладку Animations, где убедитесь в наличии флажка Import Animation. Затем перейдите на вкладку Rig и выберите в раскрывающемся списке Animation Type вариант Humanoid (ведь у нас же антропоморфный персонаж). Обратите внимание на вариант Legacy; до появления системы Mecanim настройки Generic и Humanoid были объединены.
СИСТЕМА АНИМАЦИИ MECANIM
В Unity встроена сложная система управления анимацией моделей, которая называется Mecanim. Ее основу составляет скелетная анимация, с которой вы познакомитесь в этой главе. Имя Mecanim указывает, что это более новая усовершенствованная система анимации, добавленная как замена старой версии. Последняя до сих пор доступна через настройку Legacy, но есть вероятность, что в следующих версиях Unity ее уже не будет.
Хотя анимация, которую мы будем задействовать, включена в тот же самый FBX-файл, что и модель персонажа, одним из основных преимуществ системы Mecanim является возможность наложения анимации из других FBX-файлов. Например, все враги могут пользоваться одним набором анимационных клипов. Такой подход имеет ряд преимуществ, в числе прочего предоставляя возможность структурированного хранения данных (модели сохраняются в одной папке, в то время как анимационные ролики — в другой) и позволяя экономить время за счет анимации всех персонажей разом.
Щелкните на кнопке Apply в нижней части панели Inspector, чтобы применить выбранные настройки к импортированной модели, и продолжите работу над определением анимационных клипов.
ВНИМАНИЕ На консоли может появиться предостережение (не ошибка) с текстом «conversion warning: spine3 is between humanoid transforms». На него можно не обращать внимания; он информирует о наличии в импортированной модели большего количества костей, чем ожидалось системой Mecanim.
7.4.1. Создание анимационных клипов для импортированной модели
Первым шагом по созданию анимации для персонажа будет подготовка отдельных клипов. Человек совершает разные движения в разное время. Аналогично и наш персонаж будет то бегать по сцене, то запрыгивать на платформы, то просто стоять с опущенными руками. Каждое из этих движений представляет собой «клип», который можно воспроизводить независимо.
Импортированная анимация зачастую выглядит как один длинный клип, который можно превратить в набор отдельных анимационных роликов. Это делается на вкладке Animations панели Inspector. Вы увидите там список Clips, показанный на рис. 7.13, — здесь перечислены все анимационные клипы, изначально входившие в состав единого импортированного клипа. Обратите внимание на кнопки со значками + (плюс)
и– (минус) в нижней части этого списка; они предназначены для добавления и удаления клипов. Для нашего персонажа потребуется четыре клипа, поэтому добавляйте
иудаляйте их по мере необходимости.
7.4. Анимация персонажа 181
|
К + – а |
А а , |
а а |
|
|
а |
|
а а |
|
а а |
|
|
Рис. 7.13. Список Clips на вкладке Animation |
После выбора клипа информация о нем появляется ниже, как показано на рис. 7.14. Первым идет поле с именем клипа, причем вы можете ввести новое имя. Присвойте нашему первому клипу имя idle. Теперь нужно задать параметры Start и End, определяющие первый и последний кадр выбранного клипа. Именно это позволит вырезать фрагмент из длинной импортированной анимации. Для клипа idle введите в поле Start значение 3, а в поле End — значение 141. Затем переходите к настройкам цикла.
И а а
а: а
а а
За а а а
а а
В
( а а
)
Ц • а а , а
а а а а ( ):
а а а ,
• — • , а а —
а а •
В а а а• а -а
( а• , • а ,
• а )
Рис. 7.14. Информация о выбранном анимационном клипе
ОПРЕДЕЛЕНИЕ Цикл (loop) означает запись, которая воспроизводится снова и снова. Зацикленный анимационный клип сразу же после завершения воспроизведения запускается снова.
Наш клип должен воспроизводиться в цикле, поэтому установите флажки Loop Time и Loop Pose. Кстати, зеленый цвет индикаторной точки указывает, что позы персонажа в начале и в конце клипа совпадают, что означает корректность циклического воспроизведения. В случае отдельных несовпадений индикатор становится желтым, красный же цвет указывает на совершенно разные позы.
Ниже находится набор параметров, связанных с преобразованиями корневого элемента. Слово корневой в случае скелетной анимации имеет то же самое значение, что