Как сделать графический квест
Quester — Платформа для создания и прохождения квестов (Beta)
Доброго времени суток!
Цель статьи — открыть публике платформу, которая разрабатывается в свободное от работы время и одновременно проверить, как данная платформа выдержит хабраэффект.
Содержание
Quester
Описание платформы
Все мы любим квесты и разного рода загадки. В один момент я понял, что хотел бы иметь простую возможность создавать квесты для своих друзей (и не только) в честь какого-нибудь события, ну или просто так, ради смеха.
Ну раз уж мне повезло быть разработчиком, «хотел бы иметь» обязательно должно превратиться в «надо создать»!
С точки зрения пользователя, Quester представляет собой 2 части:
Если человеческим языком — админка для создателей, приложение для игроков.
Момент, который для меня был критичен и обязателен — квесты создавать может кто угодно, ровно как и проходить.
Сам по себе квест является набором действий, которые должен выполнить игрок, Действием может быть что угодно, начиная с ответа на вопрос или чекина в какой-то конкретной точке, и заканчивая более сложными действиями вроде «Сфотографировать себя с банкой кока-колы на фоне леса» или же «встретить 10 игроков проходящих данный квест», Технически любое действие возможно в рамках данной платформы, вопрос только лишь в приоритетах и фантазии.
Ну и конечно же мы говорим о некой форме геймифицированного продукта, соответственно по окончанию квеста игрок должен получать какую-либо награду, будь то игровые очки внутри платформы, подарочный купон или настоящий подарок.
И все это полностью настраиваемо создателем квеста!
Что доступно уже сейчас
Проект в бета версии, поэтому функционал не очень обширен (но все же достоин упоминания на Хабре, я вам тут не лэндинг хочу показать, а что-то рабочее 🙂 )
Ссылки будут даны ниже, но уже тут хочу сделать оговорку — все все все работает на staging среде, продакшн среда еще не готова. Поэтому не удивляйтесь ссылкам, имеющим staging в названии.
Технические детали
Backend
Микросервисы, единственная точка входа извне — GraphQL эндпоинт, докеры кубернетисы node.js и немножко Go, MongoDB как база, все хайпово модно молодежно, готово для какой-нибудь модной конференции.
AdminTool
React, Apollo GraphQL client. Ничего особенно интересного, просто обычное веб-приложение.
Приложение
React Native, соответственно доступно на Android и iOS. Apollo GraphQL client для работы с данными, тоже ничего особенно интересного и сложного.
Как попробовать
Все задеплойно на серверах Digital Ocean в датацентра в Лондоне.
Я абсолютно забыл про блокировки в России, поэтому скорее всего айпишники моих серверов все еще в списках заблокированных.
Я приношу свои извинения всем, кому придется с этим столькнуться и честно посыпаю голову пеплом — очень неожиданный косяк с моей стороны.
В данный момент я пытаюсь найти решение (ну то есть найти облако которое точно не будет заблокированно в России, и скорее всего это будет Яндекс облако. Чтобы наверняка.)
Я повторюсь — вся платформа находится в активной разработке и еще не готова называться production-ready! Все должно работать, но и ломаться все тоже должно бесстыдно с удовольствием. Пожалуйста, имейте это ввиду.
Итак, авторизация пользователя только через Facebook. Причина максимально проста — легкость имплементации. Я не собираю о вас никаких данных кроме мэила, имени и аватарки. Про GDPR и возможность удалиться с платформы читайте ниже.
Как создать игру, ничего не умея. Часть вторая: сцена (уровень), квесты, интерактивные объекты
Предисловие
Привет^ народец, сегодня я продолжу свою попытку создать игру^ используя только информацию из интернета.
Первая часть вот тут — ТЫК.
В этой статье я попробую создать игровую комнату, она же сцена, уровень, локация и так далее, а так же попробуем прописать НПЦ (внутриигровых персонажей) с квестами, и взаимодействие с предметами. Ну что, начнём словоблудие!
Сцена
Для начала откроем наш проект над которым мы работали в прошлой статье, и переименуем нашего персонажа в Player.
Смотрим в экран и вот тут начинается главная головная боль, необходимо придумать, как будет выглядеть наш первый уровень, который необходимо построить, а главное продумать его так, чтобы он полностью удовлетворял наши потребности. Обычно для таких целей я беру пачку листов А4 и карандаш, а после несколько дней рисую разные варианты уровня, если что-то мне не нравится после рисовки, я всё равно это оставляю на будущее, поскольку в итоге из всех рисунков и собирается один более-менее играбельный уровень для игры. Но мы сейчас всё делаем по велению интернета, поэтому возьмём за идею стандартную ситуацию.
Вот такой вот незамысловатый сюжет будет в нашей сцене =)
Строительство
Тут я наверное немного поясню ситуацию. Данный Terrain я использовать не буду, у меня есть все готовые префабы для создания играбельной сцены, но для людей, которые собираются САМИ создать свою землю и объекты, прийдётся использовать данную функцию. В ней есть всё необходимое, чтобы сделать из этого квадрата равнины, горы, леса, пустыню. Необходимо просто использовать нужную Вам кисть, и натянуть текстуру. Я же в буду использовать префабы, которые шли в комплекте с персонажем, а Terrain послужит мне границами уровня. (Для тех кто всё же хочет, чтобы я создал игровую область без префабов, пишите в комментариях, тогда будет понятно, нужна ли такая информация).
Используя префабы, я начинаю строительство, выбираю для начала зелень и растягиваю её почти на весь Terrain, далее выбираю ворота, стены, горы, деревья, дорогу, и просто перетаскиваю их в сцену, немного позиционирую, а далее делаю копи-паст и собираю простейший уровень, получилось примерно так.
Все префабы ландшафта я поместил в Terrain, чтобы они не загромождали древо сцены. За 5 минут получилось невесть, что, но если провести за этим делом пару дней, то можно собрать что-то подобное.
Давайте посмотрим как поведёт наш персонаж себя в новом месте проживания. Заходим в папку Prefabs и переносим наш префаб Player в сцену, у меня он появился где-то сбоку, но я простым движением переместил его в начало каменной дороги. После удаляю из сцены Main Camera, потому как к нашему персонажу уже прикреплена камера, и дабы не было конфликтов избавляемся от камеры в сцене. Жму кнопку Play и осматриваю новые земли. Персонаж отлично себя чувствует в новом месте. Исходя из этого мы можем перейти наконец к НПЦ и квестам.
NPC или неигровые персонажи
В качестве НПЦ мы будем использовать такие же префабы рыцарей, что и наш персонаж. Давайте поставим их перед воротами.
И вот двое из ларца одинаковых с лица стоят и охраняют наши ворота. Им я сразу дал имена NPC_01 и NPC_02, давайте подойдём и посмотрим как это выглядит в игре.
Да уж, в игре это выглядит так же ужасно, как и в сцене =) Оживим наших горе-охранников, чтобы они не стояли как пугало в поле. Для этого вернёмся к нашей первой статье, где мы оживляли нашего персонажа, и проделываем туже процедуру с болванчиками у ворот. Для тех, кто не помнит, направляемся в mixamo, находим подходящие нам анимации, добавляем их в проект, создаём аниматор контроллер и прикрепляем его к болванчикам.
Я прикрепил анимацию засыпающего человека к одному болванчику, и строго стоящего второму, это мне нужно для более полного погружения для квеста. Я понимаю, что это совсем необязательно, ведь мы не пытаемся создать ААА проект прямо на коленке как Юбисофт (это лично моё мнение), но всё же и создавать Г* мне не хочется, хоть это и попытка сделать всё при помощи интернета. Наконец пришло время для квеста!
Квест
Тут мне пришлось немного использовать крота, дабы прорыть интернет для правильного скрипта и построения квеста. Его выполнение, тоже должно было работать правильно и не вызывать ошибок, и я снова на коне! Давайте приступим.
Для начала создадим папку с названием Quest, а в ней соответственно создадим три скрипта с названиями: Sword, Quest, NPC (названия произвольны, Вы можете их назвать как Вам будет удобнее, но не забывайте тогда исправить class и обращения к скриптам). Первым же будет скрипт Quest:
using UnityEngine;
using System.Collections;
public class Quest: MonoBehaviour
<
public bool quest; // отображает название квеста на экране;
public string MissionText; // название квеста;
public string ObjectTag; // тэг объекта;
public bool MissionObjects; //отображает собран предмет или нет;
public int Money; // количество денег;
if (quest)
<
GUI.Label(new Rect(20, 80, 300, 30), » » + MissionText); // значение названия квеста будет браться из скрипта NPC;
if (MissionObjects)
< // если предмет собран;
GUI.Label(new Rect(150, 80, 200, 30), «[Выполнено]»); // выводит надпись;
>
>
>
>
Его мы добавляем к нашему персонажу, и изменяем его ТЕГ на Player, тег Вы можете поставить в inspector нашего Player
Далее создаём скрипт NPC
using UnityEngine;
using System.Collections;
public class NPC: MonoBehaviour
public bool quest; //переменная, которая обозначает взят квест или нет;
public bool vis; // переменная, которая будет отображать диалог между персонажами;
public string missionText; // Текст который будет отображать наименование квеста;
public string missionTag; //Тэг объекта, который необходимо принести;
private Quest MP; // подключаем скрипт Quest;
<
MP = GameObject.FindGameObjectWithTag(«Player»).GetComponent (); // определяем что скрипт Quest будет находится на персонаже с тэгом player;
>
Создаём скрипт Sword:
using UnityEngine;
using System.Collections;
public class Sword: MonoBehaviour
<
private Quest MP; // опять подключаем скрипт Quest;
void Start()
<
MP = GameObject.FindGameObjectWithTag(«Player»).GetComponent ();
> // определяем что скрипт Quest будет находится на персонаже с тэгом player;
void OnMouseUp()
<
if (Input.GetMouseButtonUp(0)) // если при нажатии на правую кнопку мыши;
<
if (MP.ObjectTag == gameObject.tag) // и при том что тэг объекта равен тому значению которое написано в ObjectTag;
<
MP.MissionObjects = true; // то переменная принимает значение true, т.е. считается что предмет собран;
Destroy(gameObject); // и удаляем этот объект со сцены;
>
>
>
>
Добавляем скрипт к нашему мечу, и теперь необходимо создать для него тег Sword. В Inspector нажимаем на Tag выбираем Add Tag, жмём на плюсик и прописываем название Sword. Готово, тег Sword готов. Возвращаемся к NPC_01, смотрим Inspector, видим наш NPC(Script) и в строке Mission Tag прописываем sword. Если всё сделано правильно, то у нас появился наш первый квест! Давайте проверим как он работает.Запускаю игру, подхожу к НПЦ и нажимаю клавишу Е (именно она прописана в скрипте как клавиша вызова диалога).
НПЦ дал наш первый квест! Нажимаю ОК и отправляюсь на поиски меча. Как видим, у нас появилась надпись, оповещающая нас, какой именно квест мы сейчас проходим в левой части экрана.
Подойдя к мечу, нажимаю на него, и он пропадает, что говорит о правильной работе скрипта! И также появляется надпись, что мы выполнили квест, а значит нужно возвращаться и отдать меч стражнику.
Вернувшись к стражнику, он задаёт вопрос, я на него отвечаю, и вижу что квест выполнен, YoHOO!
Создаю еще одну анимацию, но на этот раз решетка находится внизу, и сохраняю её как DoorClose. После захожу в Animator, и подключаю анимацию, как мы это делали уже множество раз. Проверяю и вижу, что анимация работает, решетка непрерывно открывается =).
Ну что же, вперед к финишной прямой сегодняшней статьи =). Первым делом создаю очередной скрипт OpenDoor.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OpenDoor: MonoBehaviour
<
private Quest MP; // подключаем скрипт Quest;
<
MP = GameObject.FindGameObjectWithTag(«Player»).GetComponent (); // определяем что скрипт Quest будет находится на персонаже с тэгом player;
>
Это единственный скрипт, что я нашел в интернете, который мне подошел. Я конечно его немного подправил под мои нужны в виде MP.Money. А для того, чтобы эта строчка работала, необходимо подключить скрипт Quest, что мы и сделали в самом начале. В скриптах, что я нашел ранее, есть параметр, который даёт вознаграждение в виде денег за выполнение квеста, поэтому мы добавим одну строчку, которая нам даст 100 монет, на которые и будет отвечать скрипт открывающий решетку.
if (GUI.Button(new Rect((Screen.width — 100) / 2, (Screen.height — 300) / 2 + 250, 100, 40), «Да»)) // то появится кнопка да, при нажатии на которую;
<
quest = false; // переменная квест принимает значение false, т.е. не взят ;
MP.quest = false; // название квеста не будет отображаться на экране ;
MP.MissionText = «»; // убирается название квеста;
MP.ObjectTag = «»; // обнуляется тэг объекта;
MP.MissionObjects = false; // объект считается не подобранным;
MP.Money = MP.Money + 100;
vis = false; // диалоговое окно закрывается;
После всех манипуляций, добавляем наш скрипт OpenDoor на объект решетки, и вперед тестить!
После того как я сдал квест и получил свои 100 монет, решетка открылась =). На этом я думаю на сегодня хватит, продолжение будет скоро!
Заключение
Очередной этап создания игры закончен, абсолютно всё, что я тут проделал было взято из уроков или статей интернета.
Я конечно многое бы сделал по другому, но эксперимент есть эксперимент, и с каждой статьёй мне кажется игру я всё же закончу. Всегда рад Вашим комментариям, увидимся в следующей статье!
Большинство роликов на ютубе были абсолютно бесполезны! Зря потраченное время =).
Создание игровых уровней: советы и хитрости (часть 1)
На Хабрахабре достаточно много инди-разработчиков, некоторым из них приходится в той или иной степени заниматься левел-дизайном. В течение последних нескольких месяцев я безвылазно работал над примерно полусотней различных игровых уровней, и хотел бы поделиться своим опытом. Эта статья содержит эффективные Tips and Tricks, которые вы можете использовать, чтобы повысить общее качество вашей игры. Это ни в коем случае не пошаговое руководство, а только сборник идей и полезных советов. Первая часть статьи направлена больше на работу с визуальной составляющей игры, вторая же часть, доступная по ссылке, содержит более фундаментальные вещи, такие как прототипирование, определение размера героя и окружения, плэйтестинг и аналитику.
Левел-дизайн и нарратив
Немного лирики, прежде чем перейдём к сугубо практическому материалу. Создание уровней тесно связано с нарративом. Иными словами, практически всё, что вы делаете, рассказывает историю. Если луч света пробивается в тёмное подземелье сквозь щели в камнях, этим вы намекаете на наличие мира за пределами пещеры. Если под куполом мрачной залы стоит массивная статуя лавкрафтовского бога, вы создаёте гнетущую атмосферу, поднимаете вопросы о том, что за существо запечатлено в камне? Кто и почему ему поклоняется?
Этим я хочу сказать, что даже находясь в режиме технаря и выполняя сугубо технические задачи, левел-дизайнер должен стремиться к своей цели — оптимальным способом рассказать игроку историю и погрузить его в мир игры. Кто-то может сказать, что это не важно для PvP уровней, но вспомните классическую карту “Warsong Gulch” из “World of Warcraft”, где весь бой крутится вокруг противостояния Орков и Эльфов за ресурсы и территорию. Тем не менее, даже работая с чем-то совершенно приземлённым типа настройки коллайдеров, вы убеждаетесь, что пользователь получит именно тот игровой опыт, который вы хотите для него создать.
Визуальное разнообразие
Хороший уровень поддерживает интерес игрока, периодически изменяя ощущения от окружающего пространства. У нас есть ряд инструментов, в том числе:
Как формы использовать в левел-дизайне? Отличный пример можно найти в космическом корабле Dreadnaught в “Destiny”, где диагональные элементы архитектуры создают очень своеобразные ощущения от интерьера вплоть до едва различимого в подсознании дискомфорта.
Без помощи цветов, текста, движения, звуков и т.п. одна только смена форм по мере прохождения уровня может раскрывать новые грани истории. Вот смотрите: в начале уровня вас окружают чистые гладкие формы, а затем появляются неровности. Даже по абстракции следующей картинке вы можете примерно понять, что произошло! Вероятно, в вашем воображении уже промелькнул отрывок какой-нибудь истории.
К слову, множество интересных идей можно почерпнуть, изучая стремящийся к оригинальности пост-модернизм в архитектуре. Настоятельно рекомендую. У «современного искусства» не очень хорошая репутация, но архитектура, как правило, слишком дорогая штука, чтобы с ней игрались полные бездари.
Уникальные кадры
“Vista” — это открывающийся игроку вид, да такой, что захватывает дух. В играх с открытым миром “vista” чаще всего — это высочайшая точка на какой-нибудь башне или горе, откуда вы осматриваете окресности. Все мы помним известный процесс “синхронизации” в “Assassin’s Creed”. Для других игр эпичные виды создаются специально, а не просто позволяют нам посмотреть сверху вниз.
Отдельным подвидом “vista” можно считать “hero assets”. Как правило, это особо примечательные объекты окружения, зачастую используемые только единожды за всю игру. На них обращают внимание, их запоминают, на них ориентируются, пока бегают по уровню. В принципе, неплохим примером может быть известная Цитадель, возвышающаяся над City-17.
“Vista” и “hero assets” могут помочь вам сделать более запоминающиеся уровни, добавить им изюминку, но знайте меру. Вы можете попасть в ловушку и уделить им слишком много внимания вместо тех ассетов, которые будут использоваться сотни или тысячи раз. Здесь уместна картинка из статьи ребят из Bethesda, работавших над уровнями для Skyrim:
Десять раз подумайте, точно ли вам понадобится этот уникальный контент, и есть ли у вас силы на его создание. Особенно важно трезво оценивать свои силы инди-девелоперам, имеющим крайне ограниченные производственные ресурсы.
Интерактив и динамика
В отличие от предыдущего пункта, этот сравнительно прост в создании и применении. Что бы ни шевелилось у вас на локации — это круто! Проще говоря, любые динамичные объекты вдыхают в игру жизнь. Старайтесь добавлять горящие факелы, колышущиеся на ветру флаги, льющуюся из труб воду, водопады, качающиеся лианы, стаи птиц над головой и так далее. Трудно описать словами — это надо прочувствовать, когда на статичный уровень добавляешь динамики, и он преображается на глазах.
К динамичным объектам можно добавить и NPC. В “Белом Саду”, деревушке в самом начале “Ведьмака”, кипит жизнь — женщины стирают одежду, дети носятся по округе и играют друг с другом, старики раскуривают трубки на скамейке, мужики бьют морды в таверне. Это, разумеется, уже совершенно иной уровень динамичного окружения, требующий значительного вложения сил.
Туман как цветокоррекция
Очень интересный трюк: туман не просто оказывает существенное влияние на атмосферу и правдоподобность уровня, но также является отличным инструментом цветокоррекции. Более того, на мобильных устройствах это самый дешёвый метод цветокоррекции (”весит” порядка 3-5 fps).
В нашей игре мы реализовали простейший инструмент, плавно изменяющий туман, когда герой входит в триггер. Простейший пример: игрок бегает по уютному солнечному каньону с голубым туманом. Когда он входит в пещеру, где устроили логово головорезы, туман становится кроваво-красным, поддерживая некомфортную атмосферу опасности.
Чтобы окончательно убедить вас в силе этого инструмента, сравните скриншоты из инди игры, над которой я работаю. Из-за тумана первый выглядит как слегка пасмурный день, а второй похож на песчаную бурю.
На следующих двух скриншотах вы можете видеть очень лёгкий туман, едва заметный. Но даже при таком подходе разница в оттенке очевидна.
Есть подводный камень: надо правильно подобрать тип тумана (например, exponentional squared в Unity для этой задачи обычно подходит лучше всего) и плотность таким образом, чтобы туман не замыливал текстуры, и они не теряли контрастности.
Возвращаясь к атмосфере. Дальше идут скриншоты из Crysis 3. Как вы можете видеть, на верхнем пространство сжатое. Кажется, что дома стоят совсем недалеко от игрока. На нижней же картинке аккуратно подобранный туман визуально расширяет пространство, отодвигая дома в глубину.
Lighting is love, lighting is life
Освещение является одним из мощнейших инструментов в вашем распоряжении. Настоятельно рекомендую уделять этому достаточно сил и времени. Вместо тысячи слов:
Даже несложная геометрия с простейшими текстурами приобретает адекватный вид, когда в дело вступает освещение. Через свет мы передаем не просто техническую информацию типа времени суток и погоды, но и настроение. Аккуратная работа со светом позволяет тонко настраивать атмосферу. Вот представьте: яркий солнечный свет. На одном конце спектра у вас будет жесткое, беспощадное солнце мёртвой пустыни. На другом конце — счастливое мягкое летнее солнце, как в аниме про первую любовь токийских школьников.
Как добиться нужного эффекта от освещения? Искусство и опыт, конечно же. Готового рецепта у меня нет. Но это лирика, я же хочу поделиться ещё одним практическим трюком: критически важно иметь вариации в цвете освещения. Следуйте логике, но не забывайте о креативе. Если вы ставите источники света только там, где стоят лампы, то результат будет чёрствым и скучным. В то же время даже небольшое цветовое разнообразие от света делает уровень визуально более привлекательным.
Один из интересных приёмов: сначала ставится только логичное освещение (то есть там, где находится лампа, будет источник света), но несколько приглушённое, не финальная яркость. После этого добавляются ещё дополнительные цветные источники света. Они поднимают общую освещённость, одновременно расширяя цветовую палитру.
Есть исключения, конечно же. Например, уровень с ярким солнечным светом может преимущественно состоять только из него, и будет выглядеть отлично. В этом случае вам помогут выверенный ambient light, делающий цветными тени, а также различные постэффекты на камере, чтобы поддержать яркость солнца (пресловутый bloom, к примеру).
Блендинг света с окружением
Создавая освещение, изначально вы имеете только источник света и окружение, принимающее свет. Они находятся как бы в отрыве друг от друга. А ведь в реальности между ними был бы воздух, пыль, атмосфера.
Вот несколько методов, помогающих имитировать воздействие света на “пустое” пространство:
Постэффекты
У постэффектов сложилась дурная репутация из-за чрезмерного их использования. Из поколения в поколение передаются легенды о безвкусном применении эффекта Lens Flare. На самом же деле хорошо сбалансированные постэффекты едва заметны и не привлекают к себе внимание.
Постэффекты и освещение неразрывно связаны. На картинке ниже вы видите, как к тёмному освещению добавляется светлый туман (постэффект Global Fog из стандартного набора Unity), поверх которого накладывается Bloom.
Иными словами, работая над освещением, всегда помните про туман и постэффекты. Идея уровня, изображённого на картинке, в том, что вы находитесь в тёмной-тёмной пещере, и обнажаемые светлым туманом силуэты позволяют вам ориентироваться в пространстве.
Самым мощным постэффектом по праву считается цветокоррекция. С её помощью вы можете вносить правки в цветовую палитру с ювелирной точностью. Этот инструмент пришёл к нам из кино, и теперь ни одна ААА игра не обходится без этого. Кстати говоря, цветокоррекция используется в кино даже при работе с обычной плёнкой без применения компьютерной графики. Если посмотрите на кадры “Бойцовского Клуба” Дэвида Финчера, то сразу обратите внимание на характерный зелёный оттенок. Такого результата достигли посредством особенного состава химикатов, использованных при проявке плёнки.
Другие постэффекты, которые могут показаться вам полезными: tone mapping, bloom, antialiasing, vignette, chromatic aberration. Особо хочу отметить tone mapping, который имитирует HDR картинку на основе LDR (low dynamic range) данных. На следующей картинке меня полностью устраивала яркость света, но некоторые объекты получались чрезмерно пересвеченными.
Обратите внимание, какие изменения произошли на маленьком синем мониторе справа от прохода. Это и есть результат работы постэффекта tone mapping. Подытоживая, предостережение: старайтесь быть осторожными при работе с постэффектами. Легко обмануться, сделав бедноватый уровень с посредственным освещением, и едва посыпав его “сахаром”, решить, что у вас всё круто.
Заключение
Надеюсь эта подборка даст вам пару новых идей для ваших проектов. Я планирую написать ещё одну статью по этой же теме. В ней я расскажу про прототипирование, скейл героя и окружения, скорость бега персонажа, коллайдеры, плэйтестинг и многое другое. Она должна быть ещё более приземлённая, с меньшим количеством картинок, но хорошо упакованная моим опытом.
Между тем, если вы интересуетесь рендером освещения в Unity, у меня уже есть техническая статья на Хабрахабре. Откровенно говоря, накопив больше опыта, вижу, что в статье есть некоторые неточности, но в целом она близка к реальности. Поэтому если вы только изучаете тему освещения в Unity, материал должен быть вам полезен.