Как создать многопользовательскую игру виртуальной реальности в реальном времени (часть 1)

Опубликовано: 2022-03-10
Краткое резюме ↬ Виртуальная реальность — это новая иммерсивная среда для изучения контента, будь то фильм ( «Жизнь Пи» ), игра (« Бит Сабер ») или социальный опыт (как показано в «Первому игроку приготовиться» ). Несмотря на свою новизну, виртуальная реальность не требует радикально другого набора инструментов для разработки — те же инструменты, которые мы используем для разработки веб-игр, 3D-моделирования и других, по-прежнему применимы. В этом руководстве используются ваши знания в области веб-разработки, чтобы начать работу с виртуальной реальностью.

В этой серии руководств мы создадим многопользовательскую онлайн-игру виртуальной реальности, в которой игрокам нужно будет сотрудничать, чтобы решить головоломку. Мы будем использовать A-Frame для VR-моделирования, MirrorVR для синхронизации между устройствами в реальном времени и A-Frame Low Poly для низкополигональной эстетики. В конце этого руководства у вас будет полностью работающая демо-версия онлайн, в которую сможет играть каждый.

Каждой паре игроков дается кольцо сфер. Цель состоит в том, чтобы «включить» все сферы, где «включена» сфера, если она приподнята и ярка. Сфера «выключена», если она ниже и тусклая. Однако некоторые «доминирующие» шары влияют на своих соседей: если он меняет состояние, его соседи также меняют состояние. Только игрок 2 может контролировать доминирующие сферы, в то время как только игрок 1 может контролировать недоминирующие сферы. Это заставляет обоих игроков сотрудничать, чтобы решить головоломку. В этой первой части руководства мы создадим среду и добавим элементы дизайна для нашей VR-игры.

Семь шагов в этом руководстве сгруппированы в три раздела:

  1. Настройка сцены (шаги 1–2)
  2. Создание сфер (шаги 3–5)
  3. Делаем сферы интерактивными (шаги 6–7)
Еще после прыжка! Продолжить чтение ниже ↓

Эта первая часть завершится интерактивным шаром, который включается и выключается (как показано на рисунке ниже). Вы будете использовать A-Frame VR и несколько расширений A-Frame.

(Большой превью)

Настройка сцены

1. Давайте рассмотрим базовую сцену

Для начала давайте посмотрим, как мы можем создать простую сцену с землей:

Создание простой сцены
Создание простой сцены (большой предварительный просмотр)

Первые три инструкции ниже взяты из моей предыдущей статьи. Вы начнете с настройки веб-сайта с одной статической HTML-страницей. Это позволяет вам писать код со своего рабочего стола и автоматически развертывать его в Интернете. Затем развернутый веб-сайт можно загрузить на мобильный телефон и поместить в гарнитуру виртуальной реальности. Кроме того, развернутый веб-сайт можно загрузить с помощью автономной гарнитуры виртуальной реальности.

Начните с перехода на glitch.com. Затем выполните следующие действия:

  1. Нажмите «Новый проект» в правом верхнем углу,
  2. Нажмите «hello-webpage» в раскрывающемся списке,
  3. Затем нажмите index.html на левой боковой панели. Мы будем называть его вашим «редактором».

Теперь вы должны увидеть следующий экран Glitch с файлом HTML по умолчанию.

Глючный проект: файл index.html
Проект Glitch: файл index.html (большой предварительный просмотр)

Как и в связанном учебнике выше, начните с удаления всего существующего кода в текущем файле index.html . Затем введите следующее для базового проекта webVR с использованием A-Frame VR. Это создает пустую сцену с использованием освещения и камеры A-Frame по умолчанию.

 <!DOCTYPE html> <html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> </a-scene> </body> </html>

Поднимите камеру на высоту стоя. В соответствии с рекомендациями A-Frame VR (проблема Github) оберните камеру новым объектом и переместите родительский объект вместо камеры напрямую. Между тегами a-scene в строках 8 и 9 добавьте следующее.

 <!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity>

Затем добавьте большую рамку для обозначения земли, используя a-box . Поместите это прямо под камеру из предыдущей инструкции.

 <!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box>

Ваш файл index.html теперь должен точно соответствовать следующему. Вы можете найти полный исходный код здесь, на Github.

 <html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> <!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity> <!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box> </a-scene> </body> </html>

На этом настройка завершена. Далее мы настроим освещение для более загадочной атмосферы.

2. Добавьте атмосферу

На этом этапе мы настроим туман и индивидуальное освещение.

Превью простой сцены с мрачным настроением
Превью простой сцены с мрачным настроением (Большое превью)

Добавьте туман, который будет скрывать от нас далекие объекты. Измените тег a-scene в строке 8. Здесь мы добавим темный туман, который быстро затеняет края земли, создавая эффект далекого горизонта.

 <a-scene fog="type: linear; color: #111; near:10; far:15"></a-scene>

Темно-серый #111 линейно исчезает на расстоянии от 10 до 15 единиц. Все объекты на расстоянии более 15 единиц полностью затемняются, а все объекты на расстоянии менее 10 единиц полностью видны. Любой объект между ними частично скрыт.

Добавьте один рассеянный свет, чтобы осветлить игровые объекты, и однонаправленный свет, чтобы подчеркнуть отражающие поверхности, которые вы добавите позже. Поместите это сразу после тега a-scene , который вы изменили в предыдущей инструкции.

 <!-- Lights! --> <a-light type="directional" castshadow="true" intensity="0.5" color="#FFF" position="2 5 0"></a-light> <a-light intensity="0.1" type="ambient" position="1 1 1" color="#FFF"></a-light>

Непосредственно под источниками света в предыдущей инструкции добавьте темное небо. Обратите внимание, что темно-серый цвет #111 соответствует туману вдалеке.

 <a-sky color="#111"></a-sky>

На этом завершаются базовые изменения настроения и, в более широком смысле, настройка сцены. Убедитесь, что ваш код точно соответствует исходному коду для шага 2 на Github. Далее мы добавим низкополигональную сферу и начнем настраивать эстетику сферы.

Создание сфер

3. Создайте низкополигональную сферу

На этом шаге мы создадим вращающийся отражающий шар, как показано на рисунке ниже. Сфера состоит из двух стилизованных низкополигональных сфер с несколькими трюками, напоминающими отражающий материал.

Вращающийся, отражающий шар
(Большой превью)

Начните с импорта низкополигональной библиотеки в тег head . Вставьте следующее между строками 4 и 5.

 <script src="https://cdn.jsdelivr.net/gh/alvinwan/[email protected]/dist/aframe-low-poly.min.js"></script>

Создайте карусель, обертку и контейнер шара. carousel будет содержать несколько сфер, wrapper позволит нам вращать все сферы вокруг центральной оси, не вращая каждую сферу по отдельности, а container , как следует из названия, будет содержать все компоненты сферы.

 <a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <!-- place orb here --> </a-entity> </a-entity> </a-entity>

Внутри контейнера со сферой добавьте саму сферу: одна сфера слегка полупрозрачная и смещенная, а другая полностью сплошная. Две комбинированные имитирующие отражающие поверхности.

 <a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> </a-entity>

Наконец, вращайте сферу до бесконечности, добавив следующий тег a-animation сразу после lp-sphere внутри .orb в последней инструкции.

 <a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation>

Ваш исходный код для обертки шара и самого шара должен точно соответствовать следующему.

 <a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> <a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation> </a-entity> </a-entity> </a-entity> </a-entity>

Убедитесь, что ваш исходный код соответствует полному исходному коду для шага 3 на Github. Теперь ваш предварительный просмотр должен соответствовать следующему.

Вращающийся, отражающий шар
(Большой превью)

Далее мы добавим больше света к сфере, чтобы придать ей золотистый оттенок.

4. Зажгите шар

На этом шаге мы добавим два источника света, один цветной и один белый. Это производит следующий эффект.

Сфера, освещенная точечными огнями
(Большой превью)

Начните с добавления белого света, чтобы осветить объект снизу. Мы будем использовать точечный свет. Непосредственно перед #orb0 но внутри #container-orb0 , добавьте следующий точечный источник света смещения.

 <a-entity position="-2 -1 0"> <a-light distance="8" type="point" color="#FFF" intensity="0.8"></a-light> </a-entity>

В предварительном просмотре вы увидите следующее.

Шар освещен точечным белым светом
(Большой превью)

По умолчанию свет не тускнеет с расстоянием. Добавляя distance="8" , мы гарантируем, что свет полностью затухает на расстоянии 8 единиц, чтобы точечный свет не освещал всю сцену. Затем добавьте золотой свет. Добавьте следующее прямо над последним источником света.

 <a-light class="light-orb" distance="8" type="point" color="#f90" intensity="1"></a-light>

Убедитесь, что ваш код точно соответствует исходному коду для шага 4. Ваш предварительный просмотр теперь будет соответствовать следующему.

Сфера, освещенная точечными огнями
(Большой превью)

Затем вы сделаете свою последнюю эстетическую модификацию сферы и добавите вращающиеся кольца.

5. Добавьте кольца

На этом этапе вы создадите окончательный шар, как показано на рисунке ниже.

Золотой шар с несколькими кольцами
(Большой превью)

Добавьте кольцо в #container-orb0 непосредственно перед #orb0 .

 <a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.9" radius-outer="2" opacity="0.25"></a-ring>

Обратите внимание, что само кольцо не содержит цвета, так как цвет будет пропитан точечным источником света на предыдущем шаге. Более того, параметр material="side:double" важен, так как без него обратная сторона кольца не будет отображаться; это означает, что кольцо исчезнет на половину своего оборота.

Однако предварительный просмотр только с приведенным выше кодом не будет выглядеть иначе. Это связано с тем, что кольцо в настоящее время перпендикулярно экрану. Таким образом, видна только сторона кольца (толщина которой равна 0). Поместите следующую анимацию между тегами a-ring в предыдущей инструкции.

 <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 0 0" to="0 360 0" dur="8000"></a-animation>

Теперь ваш предварительный просмотр должен соответствовать следующему:

Золотой шар с кольцом
(Большой превью)

Создайте переменное количество колец с разными осями вращения, скоростями и размерами. Вы можете использовать следующие примеры колец. Любые новые кольца следует размещать под последним a-ring .

 <a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="2.4" radius-outer="2.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 45 0" to="360 45 0" dur="8000"></a-animation> </a-ring> <a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.4" radius-outer="1.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 -60 0" to="-360 -60 0" dur="3000"></a-animation> </a-ring>

Ваш предварительный просмотр теперь будет соответствовать следующему.

Золотой шар с несколькими кольцами
(Большой превью)

Убедитесь, что ваш код соответствует исходному коду для шага 5 на Github. На этом декор шара закончен. Закончив работу со сферой, мы добавим ей интерактивность. На следующем шаге мы специально добавим видимый курсор с анимацией щелчка при наведении на интерактивные объекты.

Делаем сферы интерактивными

6. Добавьте курсор

На этом шаге мы добавим белый курсор, который может активировать кликабельные объекты. Курсор изображен ниже.

нажав на шар
(Большой превью)

В теге a-camera добавьте следующий объект. Атрибут fuse позволяет этому объекту запускать события щелчка. Атрибут raycaster определяет, как часто и как далеко проверять интерактивные объекты. Атрибут objects принимает селектор, чтобы определить, какие объекты кликабельны. В этом случае кликабельны все объекты класса clickable .

 <a-entity cursor="fuse: true; fuseTimeout: 250" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.03; radiusOuter: 0.04" material="color: white; shader: flat; opacity: 0.5" scale="0.5 0.5 0.5" raycaster="far: 20; interval: 1000; objects: .clickable"> <!-- Place cursor animation here --> </a-entity>

Затем добавьте анимацию курсора и дополнительное кольцо для эстетики. Поместите следующее внутри объекта курсора выше. Это добавляет анимацию к объекту курсора, чтобы щелчки были видны.

 <a-circle radius="0.01" color="#FFF" opacity="0.5" material="shader: flat"></a-circle> <a-animation begin="fusing" easing="ease-in" attribute="scale" fill="backwards" from="1 1 1" to="0.2 0.2 0.2" dur="250"></a-animation>

Затем добавьте clickable класс в #orb0 , чтобы он соответствовал следующему.

 <a-entity class="orb clickable" data->

Убедитесь, что ваш код соответствует исходному коду для шага 6 на Github. В предварительном просмотре перетащите курсор с них на сферу, чтобы увидеть анимацию щелчка в действии. Это изображено ниже.

нажав на шар
(Большой превью)

Обратите внимание, что атрибут clickable был добавлен к самой сфере, а не к контейнеру сферы. Это делается для того, чтобы кольца не становились интерактивными объектами. Таким образом, пользователь должен нажимать на сферы, из которых состоит сама сфера.

На последнем этапе этой части вы добавите анимацию для управления состояниями включения и выключения сферы.

7. Добавьте состояния сферы

На этом шаге вы будете анимировать шар в выключенном состоянии при нажатии. Это изображено ниже.

Интерактивный шар, реагирующий на клики
(Большой превью)

Для начала вы сократитесь и опустите шар на землю. Добавьте теги a-animation в #container-orb0 сразу после #orb0 . Обе анимации запускаются щелчком мыши и используют одну и ту же функцию ease-elastic для легкого отскока.

 <a-animation class="animation-scale" easing="ease-elastic" begin="click" attribute="scale" from="0.5 0.5 0.5" to="1 1 1" direction="alternate" dur="2000"></a-animation> <a-animation class="animation-position" easing="ease-elastic" begin="click" attribute="position" from="8 0.5 0" to="8 3 0" direction="alternate" dur="2000"></a-animation>

Чтобы еще больше подчеркнуть выключенное состояние, мы удалим золотую точечную подсветку, когда шар выключен. Однако огни шара размещены за пределами объекта шара. Таким образом, событие щелчка не передается источникам света при щелчке по шару. Чтобы обойти эту проблему, мы будем использовать легкий Javascript для передачи события клика в свет. Поместите следующий тег анимации в #light-orb0 . Свет запускается пользовательским событием switch .

 <a-animation class="animation-intensity" begin="switch" attribute="intensity" from="0" to="1" direction="alternate"></a-animation>

Затем добавьте следующий прослушиватель событий щелчка в #container-orb0 . Это передаст щелчки шаровым огням.

 <a-entity ...>

Убедитесь, что ваш код соответствует исходному коду для шага 7 на Github. Наконец, поднимите предварительный просмотр и переместите курсор на сферу и выключите ее, чтобы переключаться между состояниями «выключено» и «включено». Это изображено ниже.

Интерактивный шар, реагирующий на клики
(Большой превью)

На этом интерактивность шара заканчивается. Теперь игрок может включать и выключать сферы по своему желанию с понятными состояниями включения и выключения.

Заключение

В этом уроке вы создали простую сферу с включенным и выключенным состояниями, которые можно переключать щелчком курсора, удобного для VR-гарнитуры. С помощью ряда различных методов освещения и анимации вы смогли различить эти два состояния. На этом завершаются элементы дизайна виртуальной реальности для сфер. В следующей части туториала мы будем динамически заполнять сферы, добавлять игровые механики и настраивать протокол связи между парой игроков.