Пошаговое создание квеста
Last updated
Last updated
В этой статье речь пойдет о создании квест-игры. В результате будет создано несколько сцен (в данном случае 5). При сканировании этих сцен у пользователя будут отмечаться отсканированные сцены (вы увидите, какие сцены отсканированы, а какие нет).
Первым шагом в создании квеста является создание проектов. В данном случае такие проекты должны быть равны количеству шагов в квесте. То есть, если вы хотите, чтобы ваш квест состоял из сканирования пяти QR-кодов, сцены также должны быть равны числу пять.
В данном случае мы рассмотрим создание квеста из пяти шагов.
Первое, что необходимо сделать, - это создать проект с отслеживанием QR-кодов. Для этого на вкладке Мои проекты необходимо нажать на кнопку Создать новый проект.
Откроется модальное окно с видами трекинга.
В данном случае это будет AR on a QR code. Нажмите кнопку Create, чтобы создать его.
Откроется пустая сцена с QR-кодом в центре.
Таких проектов предстоит создать несколько, в данном случае целых пять.
Все пять проектов готовы и переименованы.
Следующим шагом будет добавление содержимого для каждой сцены. В данном случае каждая сцена будет состоять из пяти объектов:
Основная 3D-модель,
Аудиодорожка с озвучиванием 3D-модели,
JSON, который определит, видел ли пользователь сцену,
Плагин окклюзии, позволяющий создавать эффект "портала",
Добавление базовой 3D-модели ничем не отличается от добавления любого 3D-объекта.
Сначала нажмите + в поле Model 3D.
Откроется окно добавления 3D-объекта.
Чтобы загрузить объект, нажмите на кнопку Upload в нижней части окна.
Откроется окно загрузки 3D-объекта. Здесь вы можете нажать кнопку Upload или просто перетащить файл в это окно.
Через некоторое время объект появится на сцене.
Теперь его необходимо выровнять так, чтобы QR-код модели совпадал с QR-кодом сцены.
Для добавления аудиообъекта нужно нажать на + в блоке Audio.
Откроется окно добавления аудио.
Чтобы загрузить объект, нажмите на кнопку Upload в нижней части окна.
Откроется окно загрузки аудиофайла. Вы можете либо нажать на кнопку Upload, чтобы загрузить файл, либо просто перетащить файл в это окно.
После загрузки появится окно настройки аудиофайла. Здесь можно настроить такие параметры, как Autoplay и Loop.
В этом случае необходимо включить обе настройки и нажать кнопку Next. Аудиофайл появится на сцене.
Последний (не считая файла JSON) объект, который мы добавим, — это плагин окклюзии. Чтобы добавить его, перейдите на вкладку Extensions.
Далее найдите Occlusion Cube в списке расширений и нажмите на него.
Откроется модальное окно для добавления плагина. Нажмите кнопку Install, чтобы установить его.
Затем закройте окно и вернитесь в редактор, нажав на вкладку Content.
Чтобы добавить куб окклюзии, нажмите + в поле Occlusion Cube.
Откроется модальное окно. Нажмите кнопку Save, чтобы добавить объект.
На сцене появится 3D-модель куба.
Теперь нужно покрыть поверхность сцены четырьмя кубами, а само "окно" в 3D-модели оставить открытым. Это поможет скрыть все, что находится под кубиками окклюзии, создавая эффект "окна" или "портала".
После того как объекты добавлены на сцену, пора переходить к самой сложной части: созданию сценария.
Сначала перейдите в PRO EDITOR, нажав на соответствующую кнопку в левой нижней части редактора.
Откроется продвинутый редактор.
Первое, что нужно сделать, — добавить объекты и группы, с которыми мы будем работать.
Чтобы объекты в сцене не были темными, необходимо добавить источник света. Для этого на верхней панели выберите Add → Ambient Light.
На сцене появится освещение.
Для начала создайте две пустые группы. Одна группа будет содержать вспомогательную плоскость, а вторая — сами чекбоксы.
Чтобы создать группу на верхней панели, нажмите Add → Plane.
Две добавленные группы появятся в списке объектов на сцене справа.
Далее стоит переименовать эти группы, чтобы было понятно, где и что находится.
Чтобы изменить название, выберите группу и слева, в блоке Name, впишите название.
Таким образом, названия будут следующими: border и game.
Вспомогательная группа будет содержать только один объект — плоскость. Она нужна для того, чтобы при импорте сцены в редактор MyWebAR можно было задать точный масштаб объекта.
Чтобы добавить плоскость, на верхней панели нажмите Add → Plane.
Плоскость появится на сцене.
После этого в списке объектов переместите только что добавленную плоскость Plane внутрь группы border.
Плоскость должна быть повернута на -90 градусов. Параметры плоскости:
Position: 0.0, 0.0, 0.0. Rotation: -90.0, 0.0, 0.0. Scale: 1.0, 1.0, 1.0.
Далее необходимо увеличить размер плоскости, на вкладке GEOMETRY нужно изменить два параметра: Width: 10.00, Height: 10.00.
Следующим шагом будет добавление объектов для основной группы игры. Внутри объекта game будет пять групп. Эти группы будут называться порядковыми номерами от 1 до 5.
Количество групп в объекте game должно быть равно количеству сцен.
В данном случае будет пять групп, потому что мы создали пять сцен.
Для создания группы, как обычно, нажмите Add → Group.
Группа появится на сцене. Теперь ее нужно переименовать на цифру 1.
После этого созданная группа помещается внутрь объекта game.
Аналогично, группы "2", "3", "4", "5" создаются и помещаются внутрь объекта game.
Теперь нужно поместить сами объекты внутрь созданных групп с порядковыми номерами. В моем случае это будет по два glb-файла (checked и unchecked).
Чтобы добавить 3D-объект, нажмите File → Import.
Таким образом, на сцену добавляются два объекта состояния: когда пользователь не видел сцену (back) и когда пользователь видел сцену (checked).
После этого эти объекты нужно переместить в группу game → 1.
Аналогичным образом те же самые объекты добавляются в группы 2, 3, 4 и 5. Кроме того, можно сразу же расположить эти объекты вдоль плоскости border.
Все готово.
Все объекты добавлены, и теперь можно приступать непосредственно к работе со сценарием. Для начала нам нужно создать таймер. Этот таймер нужен для запуска анимации (например, анимации самой модели или некоторых действий, выполняемых в функции update
).
Почему используется самописный таймер, а не встроенный в three.js? Это нужно для того, чтобы, если пользователь дополненной реальности потеряет маркер и направит камеру снова на маркер, сцена продолжит воспроизведение с точки прерывания, а не с самого начала.
Чтобы создать таймер, нужно щелкнуть на объекте Scene и создать новый сценарий, нажав на NEW.
Скрипт следует переименовать, назвав его, например, timers
. Для того чтобы перейти в редактор кода, нужно нажать EDIT.
Откроется редактор кода.
Здесь необходимо вставить следующий код:
В редакторе:
Нет смысла объяснять сам сценарий, за исключением последней строки window.__timers = {Timers}
. Эта строка помещает созданный объект timers
в объект window
. Это поможет нам использовать его из других скриптов.
Чтобы вспомогательная плоскость исчезала при запуске сцены, мы должны выбрать объект border и создать для него сценарий.
Перейдя в редактор кода, нужно удалить все лишнее.
Далее необходимо создать функцию start
. Эта функция будет автоматически запускаться MyWebAR при запуске сцены.
Внутри функции, используя this
изменяет параметр visible
для группы, на которой находится этот скрипт (то есть группы со вспомогательной плоскостью внутри).
Чтобы созданные объекты checked и back всегда смотрели в сторону пользователя, необходимо сделать скрипт для объекта game. Его можно назвать, например, lookAtCamera
.
Затем нужно зайти в редактор кода и удалить все.
Сначала необходимо создать две переменные:
_obj — сам объект, на котором расположен данный скрипт,
active — статус активности данного объекта
После этого необходимо создать четыре стандартные функции, которые будут запускаться самим MyWebAR, это функции: start
(запускается при запуске сцены, т.е. после инициализации), stop
(запускается при остановке проекта), update
(запускается каждый кадр).
Теперь внутри функции update
создается условие: если active
равно false
, то функция не продолжается, то есть пропускает итерацию.
Далее, после условия, создается новая переменная — THREE.Vector3
(3-мерный вектор), куда передается положение камеры (строка 17). В строке 18 мы задаем ориентацию нашей игровой группы. В строках 19-20 мы делаем так, чтобы эта группа была ориентирована на камеру.
Кроме того, необходимо добавить изменение статуса объекта (переменная active
). Для этого внутри функции start
изменим статус на true
, а внутри функции stop
на false
.
Теперь пришло время создать механику самого скрипта. Во-первых, нам нужно создать userData
для наших объектов. userData
- это данные, благодаря которым вы можете работать с объектом более удобно.
Чтобы добавить userData
, выберите объект game. На левой стороны вы увидите поле с фигурными скобками внутри.
Здесь необходимо добавить четыре значения:
Что все это означает? Давайте разберем каждое значение по порядку (для чего оно нужно).
localStorageKey — это значение поможет понять, есть ли у пользователя данные в localStorage
(начал ли он проходить квест впервые), значение localStorageKey
может быть любым, но не пустым,
sceneKey — этот параметр будет меняться в зависимости от того, на какой сцене вы собираетесь разместить этот скрипт (в данном случае это будет скрипт для сцены 1, в случае сцены 2 — значение будет равно 2, для сцены 3 — значение равно 3 и так далее),
delay — чтобы объекты состояния (checked и back) изменялись с небольшой анимацией (это скорость изменения параметра непрозрачности).
Данные userData
будут добавлены для каждой группы с порядковым номером в названии (1, 2, 3, 4, 5). Например, можно выбрать объект 1. С правой стороны вы увидите поле с фигурными скобками.
Здесь необходимо добавить три значения:
Давайте разберем каждое значение по порядку:
showEventName — управление событием, связанными с появлением объекта,
hideEventName — управлять событием скрытия объекта,
key — порядковый номер объекта (для объекта 2 это будет 2, для объекта 3 — 3 и так далее).
Например, userData
для объекта 5:
Как видите, значение key
равно 5
.
Чтобы добавить userData
, необходимо выбрать объект checked в каждой из пяти групп (группы с порядковым номером вместо имени), например, для объекта 1. С правой стороны вы увидите поле с фигурными скобками.
Здесь необходимо добавить четыре значения:
Как вы можете видеть, значения здесь такие же, как и для Добавление userData для объектов внутри групы game (объектов с именем 1, 2, 3, 4 и 5). Обратите внимание на значение key
, оно должно соответствовать той группе, в которой находится.
Чтобы создать скрипт, нужно выбрать игровой объект и создать другой скрипт. Я назову его localStorage
, так как этот скрипт необходим для работы с данными.
Чтобы открыть редактор кода, нажмите EDIT напротив имени localStorage
и удалите все содержимое в редакторе кода.
Первое, что нужно сделать, это создать переменную таймера, которая была создана в главеСоздание таймера.
Далее создаются еще три переменные:
_userData — данные, которые были записаны в userDataДобавление userData для объекта game,
_name — имя объекта,
_owner — сам объект на сцене.
Далее создаются восемь функций:
init() — функция init
, которая запускается перед запуском сцены,
getDataWithAddedSceneKey() — работа с данными из localStorage
, в зависимости от параметра sceneKey
, который находится в userData
(смотрите Добавление userData для объекта game),
getData() — получение данные из localStorage
,
saveData(data) — сохранение данных в localStorage
,
showProgress(data) — отображать результат в зависимости от того, что находится в localStorage
(работа с объектами checked и back),
sendShowItemsEvent(data) — анимация для отображения результата,
update(event) — функция update
, которая запускается каждый кадр.
Внутри init()
нужно создать переменную data
, в которую нужно записать вывод getDataWithAddedSceneKey()
(то, что вернет эта функция).
Также необходимо запустить функции saveData()
и sendShowItemsEvent()
и передать туда data
.
Внутри функции getDataWithAddedSceneKey()
мы снова создаем data
, которая является результатом функции getData()
.
Кроме того, нам нужно создать условие — если в объекте data
нет значения в пункте sceneKey
, то нам нужно изменить его на true
. Если значение есть, то мы просто возвращаем data
.
Функция getData()
содержит две переменные: str
и data
. Внутри str
находится localStorageKey
, который извлекается из localStorage
. Внутрь data
передается str
в формате JSON (в случае, если localStorage
не пуст).
Функция SaveData()
созданиет переменную str
, в которую помещается data
(преобразуется в строку, которая будет передана в localStorage
). После этого str
помещается в localStorage
.
В функции showProgress()
будет два цикла. Эти циклы необходимы для отображения объектов в зависимости от состояния сцены.
Функция sendShowItemsEvent()
содержит переменную data
, в которую помещается значение delay
из userData
. После этого создается таймер, где значение времени равно delay
.
Перед работой с функцией update()
, из-за технических особенностей редактора, необходимо добавить новую переменную в строке 1:
Окончательная версия кода для объекта game:
После написания сценария для объекта игра можно перейти к написанию двух сценариев для каждой из групп с порядковым номером в названии. В данном случае будет показан сценарий для объекта 1. Оба сценария должны быть добавлены для каждой группы (то есть для групп 1, 2, 3, 4, 5).
Первое, что мы сделаем, это напишем сценарий для появления/скрытия объектов путем изменения параметра Opacity.
ВАЖНО: Чтобы избежать путаницы с кодом, описание скриптов будет сделано в более общем виде.
Для этого необходимо создать сценарий, выделив группу. Скрипт должен иметь имя showHideByOpacity. Далее откройте редактор и удалите ненужный код.
Первое, что нужно сделать, это создать двенадцать переменных:
_userData — данные userData
для этой группы, который были созданы в подразделе Добавление userData для объектов внутри групы game (объектов с именем 1, 2, 3, 4 и 5)
_owner — непосредственно переменная с самим объектом,
_obj — объект, checked в группе,
_objsWithMaterials — результат выполнения функции getObjectsWithMaterial()
,
_duration — время работы анимации,
_showed — состояние объекта в данный момент времени (виден ли он),
_ended — закончилась ли анимация,
_startTime — время обратного отсчета,
_endTime — длительность анимации,
_startValue — стартовое значение параметра opacity,
_endValue — конечное значение параметра opacity,
_minValue — минимальное значение параметра opacity
Теперь нам нужно создать тринадцать функций:
init() — функция инициализации сцены (запускается перед началом сцены),
getObjectsWithMaterial() — необходима для поиска материальных объектов,
start() — функция, которая запускается после инициализации сцены (здесь создаются новые слушатели событий появления/скрытия объектов),
stop() — функция, которая запускается при завершении сцены (здесь удаляются слушатели событий появления/скрытия объекта),
_show(event) — функция, вызывающая появление объекта
_hide(event) — функция, вызывающая скрытие объекта,
_init() — запускается при каждом цикле появления/скрытия объекта, необходима сбросить время,
update(event) — функция, выполняемая каждый кадр,
updateScale(now) — функция для изменения непрозрачности объекта,
_getValue(now) — функция, которая генерирует значение value
,
tryStopAnimation(now) — функция для остановки процесса скрытия/появления объектов
getOpacity() — функция, возвращающая текущее значение параметра непрозрачности материала,
setOpacity(value) — функция, изменяющая значение непрозрачности для каждого объекта.
Таким образом, готовый сценарий выглядит следующим образом:
Теперь нам нужно создать второй скрипт, который будет показывать/скрывать объекты, изменяя параметр Scale. Для этого создайте новый сценарий с именем showHideByScale.
Нужно создать одиннадцать переменных:
_userData — данные из userData
для этой группы, который были созданы в подразделе Добавление userData для объектов внутри групы game (объектов с именем 1, 2, 3, 4 и 5)
_obj — непосредственно переменная с самим объектом,
defaultScale — значение по умолчания для масштаба,
_duration — время работы анимации,
_showed — состояние объекта в данный момент времени (виден ли он),
_ended — закончилась ли анимация,
_startTime — время обратного отсчета анимации,
_endTime — длительность анимации,
_startValue — стартовое значение масштаба объекта,
_endValue —конечное значение масштаба объекта,
_minValue — минимальное значение параметра opмасштабаacity
Теперь нам нужно создать десять функций:
init() — функция инициализации сцены (запускается перед началом сцены),
start() — функция, которая запускается после инициализации сцены (здесь создаются новые слушатели событий появления/скрытия объектов),
stop() — функция, которая запускается при завершении сцены (здесь удаляются слушатели событий появления/скрытия объекта),
_show(event) — функция, вызывающая появление объекта
_hide(event) — функция, вызывающая скрытие объекта,
_init() — запускается при каждом цикле появления/скрытия объекта, необходима сбросить время,
update(event) — функция, выполняемая каждый кадр,
updateScale(now) — функция для изменения непрозрачности объекта,
_getValue(now) — функция, которая генерирует значение value
,
tryStopAnimation(now) — функция для остановки процесса скрытия/появления объектов
Таким образом, готовый сценарий выглядит следующим образом:
Эти два скрипта добавляются для всех объектов с порядковым номером в названии (для объектов 1, 2, 3, 4, 5).
Остался последний сценарий — работа с самим объектом checked.
В открывшемся редакторе кода нужно удалить все лишнее.
Здесь вставлен тот же сценарий, что и в подглаве showHideByScaleРабота со скриптом для объекта внутри game (группы 1, 2, 3, 4 и 5).
Сам скрипт:
Этот сценарий добавляется для всех объектов с именем checked.
Сцена готова. Теперь необходимо экспортировать ее и настроить. Для этого первым делом нужно удалить источник света.
После этого на верхней панели нажмите File → Publish.
После этого нужно перейти в простой редактор, на сцене 1. Далее, чтобы добавить файл JSON, нажмите + в блоке JSON MAE.
На сцене появится такой же вспомогательная плоскость.
Вы можете масштабировать его, чтобы сделать флажки больше (не забывайте, что сама плоскость будет скрыта при запуске сцены).
Таким же образом нужно создать еще четыре файла JSON.
Не забудьте, что для корректной работы каждого файла необходимо изменить параметр в userData
.
Это должен быть параметр sceneKey
объекта game (смотрите в подглаве Добавление userData для объекта game).
После того как вы добавили JSON-файлы в сцену и все готово, необходимо создать мультисцену. Для этого нужно перейти на вкладку Multiscene.
Далее необходимо создать проект, нажав Create a Multiscene Project.
Откроется модальное окно добавления мультисцены.
В поле Multiscene Name нужно написать название вашей мультисцены, в поле Multiscene URL — ссылку. Далее необходимо добавить проекты, нажав на кнопку Add Projects.
Здесь нужно добавить созданные ранее проекты. В моем случае это последние пять проектов.
Для добавления необходимо нажать кнопку Add.
После этого мультисцена будет создана и появится в списке.
Если вы не хотите/можете использовать 3D-модели, вы можете создать две плоскости и заменить их материал на вкладке Material (о том, как работать с материалами, читайте в статье ).