Введение

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

Мы с коллегами из команды RnD XR (extended reality) департамента SberDevices начали думать, как можно использовать технологии 3D и XR для повышения качества взаимодействия команд на ежедневных видеовстречах в SberJazz. Так родилась идея решения SberJazz XR.

О продукте

SberJazz XR — разработан на базе платформы видеовстреч SberJazz (подробнее про сервис можно почитать тут). Решение позволяет пользователям создавать виртуальные 3D-встречи, в которых можно коммуницировать, работать или просто отдыхать и развлекаться вместе, взаимодействуя друг с другом посредством своих цифровых двойников — 3D-персонажей.

Виртуальные встречи в SberJazz XR —  это история про новый иммерсивный формат видеовстреч, про ощущение присутствия и вовлечённости в процесс.

Наша основная цель — объединять людей из разных точек планеты, предоставляя им новый опыт взаимодействия в виртуальных 3D-пространствах, а также комфортный доступ к тем инструментам, которыми они привыкли пользоваться.

Важной задачей было сделать сервис максимально простым и доступным каждому. Подключиться к виртуальной встрече в 3D так же просто, как и к классической встрече в аудио- и видеоформате.  Сейчас SberJazz XR доступен пользователям в браузере на ПК WIndows и Mac без необходимости скачивания дополнительного программного обеспечения. В ближайшей перспективе рассматриваем возможность дать пользователям доступ к решению на мобильных платформах и VR, который позволяет достичь максимального эффекта присутствия.

Ключевые возможности

Виртуальные пространства
Виртуальные пространства

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

Создание встречи в 3D

Создать 3D-комнату в SberJazz XR могут пользователи с бизнес-лицензией. На этапе создания встречи можно выбрать формат: будет ли это классическая видеовстреча в 2D или встреча в виртуальном 3D-пространстве. Для этого необходимо в браузере нажать «Создать встречу» и включить опцию «Встреча c 3D», после чего отправить ссылку-приглашение на созданную встречу участникам.

Участники переходят по ссылке-приглашению, открывают вкладку «Вид» и нажимают на кнопку «3D». При этом пользователь всегда может переключиться в более комфортный для себя режим: 3D или привычный аудио- и видеоформат в рамках той же самой встречи.

Виртуальные встречи в 3D могут поддерживать до 50 активных участников, представленных собственными 3D-персонажами в виртуальном пространстве.

Создание встречи
Создание встречи

3D-персонажи

Перед тем как войти в 3D-режим пользователь выбирает своего персонажа. Пока можно выбрать только его гендер — мужской или женский, но в самое ближайшие время мы планируем добавить возможность кастомизации — выбора одежды персонажа, причёски, цвета волос и т.д.

Выбор виртуального аватара
Выбор виртуального аватара

Локации

На текущий момент пользователям при создании 3D-встречи доступна одна локация для проведения конференций до 50 человек (с зоной ожидания начала конференции, сценой и зрительными местами). В перспективе появится возможность выбора локации на этапе создания встречи и под другие пользовательские сценарии.

Виртуальная сцена
Виртуальная сцена

Управление

Управление привычное для игровых продуктов: перемещаться персонажем по 3D- пространству можно с помощью клавиш WASD или с помощью стрелок. Удерживая левую кнопку или тачпад, можно менять угол обзора. Также с помощью скролла можно изменять режим — переключаться между видом от третьего и от первого лица. Можно прыгать/ бегать и телепортироваться в любую точку пространства по двойному нажатию левой кнопки мыши.

Подсказка по управлению в 3D
Подсказка по управлению в 3D

Режим докладчика

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

Выбор точки обзора сцены
Выбор точки обзора сцены

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

В качестве обратной связи участники встречи могут отправлять реакции — в ответ на какое-либо высказывание спикера. Реакции от участников будут видны как в 2D, так и в 3D режиме. При этом докладчик в режиме реального времени будет видеть счётчик таких реакций и понимать общее настроение аудитории. Такой инструмент полезен, когда нужно провести быстрый опрос или даже голосование.

Живые реакции

Одной из важных фичей SberJazz XR, с точки зрения взаимодействия между пользователями в виртуальном пространстве, являются живые реакции — анимированные реакции 3D-персонажа, дополненные визуальным и аудиальными эффектами. Можно поднять руку, чтобы задать вопрос, поставить лайк, похлопать в ладоши, посмеяться. Кроме этого, можно включить фронтальную камеру —  над персонажем появится кружок с видео и в виртуальном пространстве будет понятно кто есть кто.  Реакции участников отображаются как в 2D, так и в 3D режиме.

Эмоции виртуального аватара
Эмоции виртуального аватара

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

Встраиваем 3D в React приложение

SberJazz XR — кроссплатформенное решение, поэтому отдельно стояла задача имплементации в вебе. Об этом процессе расскажем чуть подробнее.

Разработку мы ведем с использованием движка Unity. Сам по себе процесс разработки приложений в среде Unity с дальнейшим экспортом отдельной WebGL сборки не представляет особых проблем: сборка включает index.html файл, который запускается в браузере.

В нашем случае Unity Instance должен быть реализован не как отдельное приложение, а в качестве артефакта в составе сервиса видеовстреч SberJazz, реализованного с использованием фреймворка React. С самим React также не возникает проблем: если в React приложение вставить: <iframe src={‘../path/to/unity/index.html’}/> с указанием пути до сборки — приложение запускается и корректно функционирует.

В процессе разработки нам также было необходимо решить вопросы:

  • интеграции Unity приложения в сервис SberJazz и работы с legacy-кодом приложения;

  • реализации двустороннего протокола общения web и Unity;

  • передачи видео из web в Unity приложение.

Для удобства мы пользуемся библиотекой react-unity-webgl. В ней доступны все необходимые нам методы для работы с Unity (ну или почти все). Для инициализации Unity Instance используется hook useUnityContext. Полученный unityContext даёт возможность взаимодействовать с Unity Instance, обмениваться сообщениями, отслеживать загрузку и тд.

import { Unity, useUnityContext } from 'react-unity-webgl';

const UnityContent: FC = () => {
const unityContext = useUnityContext({
    loaderUrl: `./Build/build_unity.loader.js`,
    dataUrl: `./Build/build_unity.data`,
    frameworkUrl: `./Build/build_unity.framework.js`,
    codeUrl: `./Build/build_unity.wasm`,
    streamingAssetsUrl: `./StreamingAssets/`,
    companyName: 'SberDevices',
    productName: `Jazz XR`,
    productVersion: `v.0.0.1`,
  });

return <Unity unityProvider={unityContext.unityProvider} />

Для очистки Unity Instance перед размонтированием компонента, в котором он находится, должен был быть использован метод:

unityContext.unload();

Однако данный метод не работает для версий Unity 2021.2 и старше, в связи с известным багом Unity.

Чтобы обойти данное ограничение и иметь возможность выгружать Unity Instance из памяти без ошибок, мы использовали iframe.

const App:FC = () => {

return <iframe>
	<UnityConten/>
</iframe>
}

Протокол общения React-Unity

На скриншотах выше можно заметить, что весь UI реализован поверх Unity сцены. Так сделано, в первую очередь потому, что мы встраиваем 3D в уже готовое приложение, а значит, будем транслировать ивенты от имеющегося UI в 3D сцену. Логику делить не стали, продолжили делать UI на React’e. А для отправки сообщений в Unity используем уже созданный контекст

Отправляем сообщения из React в Unity:

function ToggleSounds(isActive: boolean) {
    unityContext.sendMessage("SoundController", "ToggleSounds", isActive);
  }

// SoundController - это имя объекта внутри сцены
// ToggleSounds - метод написаный на C#, который мы вызываем
// isActive - параметры передаваемые в этот метод (могут быть лишь boolen, string, int)

Принимаем сообщение в Unity:

using UnityEngine;

public class SoundController : MonoBehaviour {
  public void ToggleSounds (bool isActive) {
    Debug.Log ($"Environment sounds now  is {isAcive}");
  }
}

Передаем видео внутрь 3D-сцены

Каждый пользователь при входе в 3D-сцену отправляет свои данные по аналогии с переключением звука, среди этих данных есть следующее:

type User =
{
	uid: string;
	name: string;
	cameraMuted: boolean;
	screenMuted: boolean;
	...
}

Со стороны React в момент включения камеры/выбора повтора экрана создаём Canvas, в который записываем видеопоток и присваиваем ему uid пользователя. Со стороны Unity получаем патч с новыми данными, и, если видим значение cameraMuted: false или screenMuted: false, понимаем, что клиент включил камеру/запустил повтор экрана.

С помощью плагина JSLib мы можем получить доступ к элементам HTML документа, в котором запущен наш Unity Instance. Там мы ищем canvas по uid и копируем текстуру из canvas в заранее выделенную текстуру внутри Unity сцены. Пример реализации можно посмотреть тут.

Синхронизируем информацию между пользователями 3D-встречи

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

Цвет одежды персонажа и его скин задаются числами, поскольку выбор цвета и скина персонажа происходит из заранее известного всем клиентам списка. После получения этих данных любой клиент без труда сможет сопоставить конкретного персонажа, его цвет с пользователем. Вот так выглядит начальный пакет данных, отправляемый в момент подключения:

{
	roomId: string,
	userId: string,
	colorId: number,
	skinId: number
}

Кроме этого, синхронизируются данные о положении, направлении взгляда и скорости движения персонажей внутри 3D-сцены. Сообщения отправляются клиентами с высокой частотой.

При выборе сетевого фреймворка мы, в первую очередь, обращали внимание на быстродействие протокола обмена данными. При определении структур данных на сервере разработчик задаёт её через, так называемые, схемы данных. Каждый элемент такой схемы — поле класса, отмеченное атрибутом. Такого рода структуры позволяют использовать описанные в схеме данные не только на сервере, но и на клиенте через механизм генерации кода.

Приняв сообщение от клиента, сервер обновляет свою модель данных новыми данными. С определённой периодичностью сервер отправляет всем клиентам обновление с новым состоянием модели комнаты. Вот структура данных, которые пользователи передают на сервер:

{
	userId: string,
	x: number,
	y: number,
	z: number
}

А вот структура данных, которую сервер присылает всем клиентам с определенным периодом:

Player:
{
	userId: string,
	position: Vector3,
	direction: Vector3
}

State:
{
	players: [Player]
}

Реакции синхронизируются как события от сервера конференции, а не от риалтайм сервера. Это как раз связано с тем, что посылать и принимать реакции можно не только в 3D, но и в обычных конференциях. Примерный формат передачи данных для эмоции выглядит вот так:

{
	userId: string,
	emotionId: string
}

Собственная zero-code система имплементации логики

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

Компонентный редактор логики
Компонентный редактор логики

Технически система построена на трех главных компонентах: событие, реакция и действие.

Событие представляет собой источник информации об изменении состояния системы: клик на кнопку, активация коллайдера, глобальное событие.

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

Реакция — это контейнер, главная задача которого связать источники информации и нужные действия.

Со временем мы добавили варианты более сложных конструкций:

  • стейт-машины — у каждого состояния стейт-машины можно задать условия перехода в другой стейт и действия, выполняемые на входе и выходе из стейта.

  • условные действия — даже при наступлении определенного события действие может не запуститься, если его условия не выполнены.

  • контейнеры данных — для реализации сложной логики необходимо хранить промежуточные значения и состояния.

Все обладатели бизнес-лицензий SberJazz уже сейчас могут протестировать новый формат встреч, чтобы удивлять и удивляться.

Комментарии (4)


  1. MAXH0
    28.11.2023 17:15
    +1

    но в самое ближайшие время мы планируем добавить возможность кастомизации — выбора одежды персонажа, причёски, цвета волос и т.д.

    А еще можно ввести цветовую дифференциацию штанов. "Когда у общества нет цветовой дифференциации штанов, то нет цели! А когда нет цели — нет будущего!" А на штаны можно еще и NFT метки ставить, чтобы подчеркнуть уникальность.

    Так что есть куда копать!


  1. Hungryee
    28.11.2023 17:15
    +1

    Опыт Цукерберга о полной бесполезности и бессмысленности подобных проектов никого видимо не учит…

    Еще миллионы можно распиливать


    1. Sercius
      28.11.2023 17:15
      +2

      им без этого нельзя, они там ВЫГОРАЮТ.


  1. AlexanderKudryavy
    28.11.2023 17:15

    Выглядит очень очень плохо