
- •Предисловие
- •Введение
- •Благодарности
- •О книге
- •Перспективы
- •Условные обозначения, требования и доступные для скачивания данные
- •Автор в Интернете
- •Об авторе
- •Глава 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. Назначение материала

8.5. Заключение 213
DisplayItems(); return true;
}
...
Листинг 8.23. Добавление кнопки здоровья в базовый UI
...
}
}
}
Выделенный курсивом код в сценарии уже был, foreach (string item in itemList) { ¬ здесь он приведен в качестве точки отсчета.
if (GUI.Button(new Rect(posX, posY, width, height), "Equip "+item)) { Managers.Inventory.EquipItem(item);
}
if (item == "health") { ¬ Начало нового кода.
if (GUI.Button(new Rect(posX, posY + height+buffer, width, height), "Use Health")) { ¬ Запуск вложенного кода при щелчке на кнопке.
Managers.Inventory.ConsumeItem("health");
Managers.Player.ChangeHealth(25);
}
}
posX += width+buffer;
Новый метод ConsumeItem(), по сути, диаметрально противоположен методу AddItem(); он проверяет наличие указанного элемента в инвентаре и уменьшает значение, если таковой не обнаружен. Умеет он реагировать и на ситуацию, когда количество элементов уменьшается до нуля. Код UI вызывает этот новый метод работы с инвентарем, который, в свою очередь, вызывает метод ChangeHealth(), с самого начала присутствовавший в сценарии PlayerManager.
Если вы соберете несколько пакетов здоровья, а затем ими воспользуетесь, на консоли появятся соответствующие сообщения. Вот вы и узнали еще один вариант использования элементов инвентаря!
8.5. Заключение
Управлять устройствами можно как посредством нажатия клавиш, так и с помощью триггеров столкновения.
Объекты, для которых включена имитация реальных физических явлений, могут реагировать на силу столкновения и зоны триггеров.
Сложными игровыми состояниями управляют через специальные объекты общего доступа.
Коллекции объектов можно систематизировать с помощью таких структур данных, как List или Dictionary.
Отслеживание подготовленных состояний элементов инвентаря позволяет влиять на другие части игры.
Ч а с т ь III УВЕРЕННЫЙ ФИНИШ
Вы уже много знаете о Unity. Вы умеете программировать элементы управления персонажем, создавать блуждающих по сцене врагов и добавлять в игру интерактивные устройства. Вы даже способны пользоваться при создании игр как двухмерной, так и трехмерной графикой! Всего этого почти достаточно для разработки полноценной игры. Почти, но не совсем. Вам нужно изучить еще ряд вещей, таких как добавление в игру звука, кроме того, вы должны суметь собрать воедино все разрозненные фрагменты, с которыми мы до этого работали.
Вы уже на финишной прямой, осталось всего четыре главы!

9 |
Подключение игры |
к Интернету |
33 Генерирование графики для неба с помощью скайбокса 33 Скачивание данных с помощью веб-объектов в сопрограммах
33 Анализ распространенных форматов данных, таких как XML и JSON 33 Отображение скачанных из Интернета изображений 33 Отправка данных на веб-сервер
Вэтой главе мы рассмотрим способы отправки и получения данных по сети. Все созданные нами проекты, представляющие различные игровые жанры, располагались исключительно на вашей машине. А как известно, подключение к Интернету и обмен данными становятся все более важным аспектом игр всех жанров. Многие игры существуют исключительно в Интернете с постоянным подключением к сообществу игроков; для их обозначения используется аббревиатура MMO (Massively Multiplayer Online — массовая многопользовательская онлайновая игра). Шире всего известны так называемые массовые многопользовательские ролевые онлайновые игры (Massively Multiplayer Online Role-Playing Games — MMORPG). Даже если постоянное подключение для игры не требуется, современные видеоигры оснащены такими функциями, как, например, отправка сведений о набранных очках в глобальный список лучших результатов. В Unity они тоже поддерживаются, так что мы подробно рассмотрим данную функциональность.
ВUnity поддерживаются разные варианты передачи данных по сети, так как существуют разные варианты задач. Но в этой главе будет рассматриваться в основном наиболее общий вид сетевых взаимодействий — отправка HTTP-запросов.
ЧТО ТАКОЕ HTTP-ЗАПРОСЫ?
Я думаю, что большинство читателей уже знают, что представляют собой HTTP-запросы, но на всякий случай дам небольшое пояснение: HTTP — это протокол отправки запросов к веб-серверам

216 Глава 9. Подключение игры к Интернету
и получения оттуда ответов. Например, когда вы щелкаете на расположенной на веб-странице ссылке, ваш браузер (клиент) отправляет запрос на определенный адрес, а расположенный по этому адресу сервер возвращает новую страницу. Такие запросы выполняются различными методами, например существуют методы GET и POST, используемые для получения и отправки данных соответственно.
Популярность HTTP-запросов объясняется их надежностью. При проектировании как самих запросов, так и предназначенной для их обработки инфраструктуры, закладывается устойчивость к сбоям и способность справляться с самыми разными видами неполадок.
Разрабатываемая в Unity онлайновая игра на базе HTTP-запросов будет, по сути, толстым клиентом (thick client), взаимодействующим с сервером в стиле Ajax. Для сравнения вспомните, как работают современные одностраничные веб-приложения (в отличие от старых добрых веб-страниц, генерируемых на стороне сервера). Хорошее знание принципов старой школы порой заставляет опытных разработчиков делать неверные шаги. Видеоигры зачастую имеют куда более строгие требования к производительности, чем веб-приложения, и именно эта разница в требованиях может влиять на проектные решения.
ВНИМАНИЕ Для веб-приложений и видеоигр понятие времени может иметь разный смысл. При обновлении скачиваемой страницы половина секунды, как правило, вообще ничего не значит, в то время как в разгар активных действий в игре подобная задержка способна испортить все удовольствие. Понятие «быстро» целиком и полностью зависит от ситуации.
Онлайновые игры, как правило, подключаются к специально предназначенному для этой цели серверу; но в целях обучения мы будем подключаться к открытым источникам данных, включая источники прогнозов погоды и доступных для скачивания изображений. Последний раздел этой главы потребует от вас настройки собственного веб-сервера; вы можете просто пропустить этот раздел, хотя я, естественно, на примере программного обеспечения с открытым исходным кодом предлагаю вам максимально простой способ настройки.
В процессе работы над упражнениями этой главы вам много раз придется прибегать к HTTP-запросам, чтобы понять принцип их работы в Unity:
1.Настройка натурной сцены (а именно, создание неба, реагирующего на данные метеонаблюдений).
2.Написание кода, запрашивающего прогноз погоды из Интернета.
3.Анализ ответа и корректировка сцены в соответствии с полученной информацией.
4.Скачивание и отображение графики.
5.Отправка данных на ваш собственный сервер (в нашем случае это будут записи журнала о погоде за прошедшее время).
Игра, на примере которой будет демонстрироваться проект этой главы, не имеет значения. Мы будем добавлять к проекту новые сценарии, никак не затрагивая существующего кода. Например, я воспользовался демонстрационным роликом из главы 2, так как там есть возможность от первого лица наблюдать за изменениями неба. Проект этой главы не имеет непосредственной связи с игровым процессом, но очевидно, что возможность передачи данных по сети пригодится в большинстве