Привет, друзья! В прошлом посте я спрашивал, есть ли интерес к пошаговому описанию создания своей мультиплеерной игры на Unity. Вы дали добро... Поэтому - поехали =)
Ах, да. Внимание! Очень длиннопост! + гифки и картинки.
Сразу хочу сказать, что посты будут ориентированы на новичков в геймдеве и программировании. В том числе новичков в Unity. Я буду стараться пояснять многое, но пожалуйста, не ленитесь пользоваться гуглом. Иначе придётся растягивать на очень уж длиннопосты. Все исходники я буду выкладывать в опенсорс и прикреплять unitypack-и. Чуть позже, когда мы с вами прикрутим мультиплеер, сделаю и онлайн демо.
Господа опытные разработчики. Очень прошу вас. Не проходите мимо. Мы собираем OpenSource проект. Своего рода StarterKit для TPS Action. Уверен, такие штуки будут полезны очень многим разработчикам. А особенно - разработчикам начинающим. Давайте сделаем мир чуточку лучше. Давайте учиться сами и помогать учиться начинающим. Предлагайте свои доработки. Не бойтесь исправлять меня. Я сам в Unity относительно новичок.
И для затравки то, что у нас сегодня получится в итоге:
Кто-то, возможно, заметил, что на гифке представленны ассеты из бесплатного набора Unity. Не бойтесь, я буду использовать только готовые модели. Потому, что это быстро. И потому, что это бесплатно. Весь код в проекте будет либо мой. Либо, в последствии, ваш. Я искренне верю и надеюсь, что опытных разработчиков наш скромный проект со временем заинтересует. А пока будем набирать массу, чтобы можно было чем-то удивить.
Итак. Первое, что нам нужно будет сделать - это скачать и установить Unity5. По ссылке это можно сделать абсолютно бесплатно. Затем - найти какой нибудь содержательный видео гайд по интерфейсу Unity, горячим клавишам и прочему-прочему. Я не буду об этом рассказывать, ибо этой информации уже слишком много в сети (кто не умеет делать игры на Unity - пишет об этом уроки. И да, я знаю, что говорю, возможно, в том числе и о себе).
Когда вы уже уверенно чувствуете себя в куче каких-то непонятных окон - давайте начнём собирать сцену. Для этого нам понадобятся бесплатные ассеты от Unity Technologies. Найти их можно в Asset Store на сайте, или прямо в редакторе, по комбинации клавиш Ctrl+9.
Там вам нужно будет найти вот этот вот демонстрационный проект (на картинке выше). И нет, мы не будем работать с VR. Просто визуально эта сцена мне показалась наиболее подходящей. Да и там есть бесплатный персонаж... Ну просто чудо, а не ассет. Качаем и распаковываем. У вас для этой демки создастся отдельная папке в окне project. Загляните в неё. По открывайте там вложенные папки. Посмотрите, где что лежит. И подумайте, почему оно так. Потому, что сейчас мы приступим к созданию собственной структуры проекта.
Итак, вы вероятно заметили, что проект имеет несколько основных разделов, делящих (простите за тавтологию) проект по типу файлов. Это анимации, звуки, модели и т.п. Такой подход применяется в большинстве проектов. Давайте и мы в этот раз не будем отклоняться от этого достаточно логичного принципа. Создадим следующие папки и подпапки:
1 Animations - будет содержать анимации и контроллеры анимации. Позже мы разобьём эту папку ещё на несколько, но это будет очень не скоро. Когда наши анимашки начнут накапливаться.
2 GUI - будет содержать файлы, которыми мы будем оформлять наш интерфейс. В ней:
2.1 Fonts - шрифты. Чтобы было, с чем поиграться (да, я веб разработчик, это больное).
2.2 Images - изображения. Тут будут находиться различные барчики и иконки.
3 Models - Понятно из названия. 3D модели, текстуры и материалы. Куда будем девать шейдеры пока не решил, нам с вами до них ещё долго. В ней создайте следующие папки:
Enviorments, Players, Vehicles, Weapons и Small objects. Окружение (игровой мир), модельки персонажей (мы их чаще будем называть аватарами, хотя как пойдёт), транспорт, оружие и различные маленькие объекты, которые, возможно, не относятся к окружению и с которыми мы будем взаимодействовать. Поехали дальше.
4 Resources - здесь будут располагаться префабы. Это тоже что-то вроде моделей, но не модели. Это их экземпляры, уже имеющие какие-то компоненты и... Ай, ладно. Не забивайте голову. Более подробно о префабах я расскажу, когда мы будем делать мультиплеер. Это уже очень скоро. Главное - создайте здесь подпапки:
Players (персонажи), Points (префабы различных чекпоинтов) и Vehicles (транспорт).
5 Scenes - здесь будут находиться наши игровые сцены. Своего рода виртуальные миры. Их будет не много. А мир, так вообще один (скорее всего). Но сцены достойны иметь свой каталог, ибо к ним мы будем часто обращаться. И последнее:
6 Scripts - это наши скрипты. Здесь будет два вложенных каталога:
6.1 Controllers - контроллеры.
6.2 Managers - менеджеры.
Вот тут я немного боюсь породить небольшой холивар. Но в программировании без этого никуда. И так, Unity - компонентно-ориентированный движок, скрипты (даже это слово многим не нравится, но сам редактор предлагает создать скрипт) в котором пишутся на объектно-ориентированном языке C#. UnityScript в топку, ибо это даже не Js, это разработанный под Unity язык с Js подобным синтаксисом. Да, я морально готов к гневным комментариям =)
К чему я это всё. Мы с вами будем создавать отдельные контроллеры. Такие, как PlayerController, WeaponController и им подобные. Это и есть компоненты, которые мы будем "вешать" на наши игровые объекты и эти компоненты будут позволять нам стрелять (если это WeaponController), бегать (если это PlayerController) и так далее. А менеджеры, это какие-то общие скрипты, которые будут управлять не игровыми объектами, а целыми процессами. Например GameManager у нас будет отвечать за игровую логику. А NetworkManager позволит управлять процессами сетевого взаимодействия.
Ладно, с этим разобрались. Сильно не забивайте голову. Всё будет понятно, когда мы начнём с этим работать. Теперь у нас есть готовые ассеты, в которых вы уже ковырялись. И структура проекта. Давайте соберём сцену. На самом деле, я дам ссылку на скачивание исходников. Поэтому моё описание сборки сцены будет походить на гайды "как нарисовать кота". Ну вы поняли. Смотрим скрин ниже:
Во первых по нему вы можете перепроверить свою структуру папок. Во вторых - посмотреть, что вы сейчас будете делать. И в третьих удостовериться, что средствами Unity у вас это сделать не получится потому, что в скачанном вами ассете есть лишняя стена, которую я убрал в Blender-e. Но всё же. Перед тем, как тупо качать unitypack с исходниками, включающими сцену - постарайтесь максимально воссоздать то же самое в ручную.
Посмотрите видео гайды о том, как работать с файлами в Unity и как создавать сцены из примитивов. Потратьте на это день - два или даже три. Посты я буду публиковать со средней периодичностью - один пост по GTO-R StarterKit в неделю. У вас будет время поковыряться самостоятельно. А чем больше вы сделаете руками, тем больше получите опыта. Это правда.
И так, когда у нас есть сцена - по ней уже можно бегать. Но бегать нам пока не кем. Давайте создадим условного персонажа-капсулу и научим его перемещаться. С этого момента я буду рассказывать немного подробнее. Здесь уже начинается эксклюзив. Если вы не до конца не понимаете, что происходит в следующем абзаце - не пугайтесь. Если вы вообще не понимаете, о чём я говорю - посмотрите любой русскоязычный туториал по созданию сцен из примитивов. Там дадут хорошую базу.
Поехали. Для начала - создайте в сцене пустой (Empty) объект. Он и будет нашим игроком, но на уровне абстракции. Назовём его Player. Далее, перетащите в него объект Main Camera. Это можно сделать в инспекторе. Теперь - кликните правой кнопкой мыши по нашему объекту Player и выберите создать -> капсулу. Назовите её Avatar. Это будет телом нашего игрока. Удалите коллайдер с этого объекта. Столкновения у нас должны будут обрабатываться игроком. И теперь примените материал MazeLowMan, который можно достать из скаченного нами ассета. Замечательно! Персонаж уже на 80% готов. Выберите объект Player и посмотрите на сцену. Если вы его ещё не достали, скорее всего он у вас находится ниже уровня пола. Достаньте его за видимые контроллеры (стрелочки) и установите так, чтобы цилиндр еле касался пола.
Теперь займёмся камерой. Заходим в окно Game и в иерархии выбираем объект Main Camera.
Теперь нам необходимо настроить удобный вид из неё. Чтобы картинка подходила для пикабу, мне приходится снимать в окне, шириной 800px. Поэтому я не буду выставлять точные значения. Сделайте так, как вам будет удобно наблюдать за персонажем от третьего лица. Желательно, чтобы камера была смещена не только назад и вверх. Но и немного вправо. Так, в последующем, будет удобнее целиться. Кстати, если камера вначале у вас вообще не рядом с персонажем - поставьте в Transform Position все нули. Так она переместится в самый центр персонажа.
Последние 10% в настройке нашего персонажа - это сделать его твёрдым телом имеющим свою массу. Делается это путём настройки двух компонентов:
И так. Выделяем персонажа Player в иерархии. Добавляем компонент Physics->Capsule Collider. Далее нам необходимо только настроить высоту зелёной капсулы, которая будет являться нашей физической оболочкой. Далее добавляем компонет Rigidbody. Из того же пункта Physics. Этот компонент отвечает за обработку взаимодействия физического объекта с окружением. В нём мы добавляем вес и устанавливаем галочки во всех трёх осях Freeze Rotation.
Для чего это нужно? Риджидбади, при запуске игры, обрабатывает все столкновения и делает просчёт, как повело бы это тело при столкновении. Обратите внимание, что наша капсула (как минимум) вертикальная и с очень неустойчивым основанием. Что бы случилось с такой двухметровой капсулой, стой она у вас без опоры? Она бы рухнула. То же самое сделает и Unity. Это физически корректно, но в данном случае нам это не нужно.
Всё, персонаж готов. Всё, что нам осталось - научить его ходить. Для этого нам необходимо создать новый скрипт. Скрипт у нас будет называться Player Controller и, соответственно, создать его необходимо в папке Scripts->Controllers. Возьмите этот скрипт и перетащите мышью на объект Player. Он добавится к нему, как компонент. Это потом позволит вам управлять нашим персонажем.
Далее - скрин исходника. Огромная просьба. Если вы хотите научиться программировать - набирайте ручками. Это полезно. Если не хотите... То почему вы читаете пост про геймдев? =)
Я не буду пояснять каждую строку. Поясню большую часть моментов, но думаю, описывать переменные (тем более, что они хорошо закомментированы) - не имеет смысла.
Кстати, пока не забыл. Я допустил ошибку по невнимательности. Точнее просто забыл сделать, как надо. Мы создаём переменную avatar. Это единственная переменная объекта, которую необходимо задавать в ручную. Просто захватите объект Avatar в иерархии и перетащите в поле Avatar на компоненте PlayerController. Но только после того, как мы его напишем.
И так самое интересное:
Строка 7 и 11. Такие элементы позволяют выводить заголовки для групп настроек в инспектор. Удобно, если настроек планируется много.
Строка 31. Метод поиска объекта по типу. По всей сцене мы ищем объект типа "камера". Благо он у нас такой один.
Строки 47 и 48. Методы Transform.Translate и Transform.Rotate. Давайте на секунду заглянем в юнити. Выделите в иерархии любой объект и посмотрите в инспектор. Самым первым компонентом везде (кроме элементов UI, но их у нас в сцене и нет) стоит компонент Transform. Он отвечает за положение объекта в пространстве, его размер и направление. Так вот транслейт - двигает объект. Ротейт - вращает. Они оба делают это, используя компонет трансформ.
Строка 51. Тут всё немного сложнее. Да, мы тоже вращаем объект. Но как видно из названия метода - вращаем вокруг чего-то. То, вокруг чего мы вращаем задаётся первым значением. Это позиция игрока. Вторым - ось, вокруг которой вращаем. А третьим - мы должны указать, на сколько собственно вращать.
С 55 по 60 строку мы просто получаем данные ввода. И если с осями мыши ещё понятно, то почему клавиши W A S D тоже считаются осями? Всё просто. Unity - кросплатформенный движок. Чтобы не мучать себя с программированием каждой клавиши на каждом устройстве, в PlayerSettings можно задать настройки осей управления. Оси для мышей и клавиатур работают по умолчанию.
Вот и всё. Очень простой и элегантный скрипт. Я немного поленился и не доделал ограничения по высоте наклона вверх и вниз. Точнее я удалил этот метод при дебаге и поленился восстанавливать =) Поэтому не пугайтесь, что у нас есть незадействованные переменные. Мы их обязательно используем в следующий раз. А теперь заходите в редактор, убедитесь, что вы повесили PlayerController на своего Player-a, установите следующие настройки:
И можете побегать по нашей карте. Там есть один небольшой баг с проваливанием сквозь текстуры. Разберётесь сами, как его исправить?) Если нет - покажу в комментариях.
Спасибо, что дочитали до конца. Отдельное спасибо, если честно выполняли мои рекомендации =) Это пойдёт вам на пользу в будущем. Если вам понравилось - подписывайтесь на меня и следите за новостями. Не забывайте ставить плюсы, это лучшая благодарность для автора )
Самая актуальная информация по проектам нашей команды постится в группу в контакте: vk.com/gtogamedev. Подписывайтесь, там я выкладываю исходники ещё до публикации поста (ибо на написание поста у меня ушло 4 часа). Если есть вопросы лично ко мне - добро пожаловать! Пишите мне на vk.com/tonykotdev, буду рад видеть пикабушников)
И, конечно, ссылка на исходники на Google Drive.