Проверка доступности session и поддержки устройства
Перед запуском AR обычно сначала нужно проверить, доступна ли session и поддерживает ли текущее устройство необходимые AR-функции. В этой статье объясняется, как выполнять такие проверки.
Перед началом
- Изучите Введение в ARSession, чтобы понять основные понятия, состав и рабочий процесс session.
- Изучите Поддержка устройств и отчеты, чтобы понять основы поддержки устройств и отчётов session в Unity.
- Узнайте, как создать session.
Получение отчёта в процессе запуска
Если session запускается сразу после assemble, отчёт session можно получить через событие StateChanged.
Нужно подписаться на событие StateChanged до запуска session; обычно безопасно делать это в Awake():
void Awake()
{
Session.StateChanged += HandleSessionStateChange;
}
Состояния session, на которые нужно обращать внимание в обработчике события: Ready и Broken. Состояние Ready означает, что session успешно запущена, то есть доступна на текущем устройстве. Состояние Broken означает, что запуск не удался, то есть session недоступна на текущем устройстве.
Состояние Broken не всегда появляется при неподдерживаемом устройстве. Поэтому нужно также использовать SessionReport.BrokenReason для получения точной причины сбоя.
void HandleSessionStateChange(ARSession.SessionState status)
{
if (status == ARSession.SessionState.Ready)
{
// session доступна на текущем устройстве
}
else if (status == ARSession.SessionState.Broken)
{
// session недоступна на текущем устройстве
if (Session.Report.BrokenReason == SessionReport.SessionBrokenReason.NoAvailabileFrameSource ||
Session.Report.BrokenReason == SessionReport.SessionBrokenReason.FrameFilterNotAvailabile)
{
// выбранный компонент не поддерживается текущим устройством
}
else
{
// причина не связана с устройством
}
}
}
Причины SessionReport.SessionBrokenReason.NoAvailabileFrameSource и SessionReport.SessionBrokenReason.FrameFilterNotAvailabile означают, что компоненты session недоступны на текущем устройстве; остальные причины обычно не зависят от устройства. Строго говоря, эти две причины означают, что текущая конфигурация, и только она, не может запускать AR-функции на этом устройстве. Под конфигурацией понимаются функции и настройки, выбранные в объекте session. Подробный отчёт о доступности можно получить из Report.
В случае SessionReport.SessionBrokenReason.NoAvailabileFrameSource, если при запуске session через обновление списка устройств онлайн обнаружится, что устройство уже поддерживается, session может автоматически восстановиться.
Получение отчёта до запуска
Если вы хотите принять решение до запуска session и по ситуации решить, запускать её или нет, можно вручную вызвать Assemble() и использовать событие AssembleUpdate для получения отчёта о доступности компонентов.
Нужно подписаться на событие AssembleUpdate до assemble session.
Session.AssembleUpdate += OnAssembleUpdate;
На первой фазе assemble всё ещё можно использовать ARSession.SessionState и Report, чтобы оценить поддержку session. Но отчёт второй фазы не обновляется в session.
Поэтому при ручном вызове Assemble() обычно нужно обрабатывать отчёт о доступности в событии AssembleUpdate, чтобы понять, доступна ли session на текущем устройстве.
Особенно важно следить за доступностью компонентов в списке SessionReport.AvailabilityReport.FrameSources. Если доступен хотя бы один frame source, то часть SessionReport.AvailabilityReport.FrameSources считается доступной на текущем устройстве.
Также нужно обращать внимание на список SessionReport.AvailabilityReport.FrameFilters. Критерий зависит от параметров assemble: может требоваться, чтобы были доступны все frame filters, или только часть. По умолчанию нужны все frame filters.
В конфигурации по умолчанию можно использовать следующий код, чтобы проверить, доступны ли компоненты session на текущем устройстве:
void OnAssembleUpdate(SessionReport.AvailabilityReport report)
{
if (report.FrameSources.Any(f => f.Availability == SessionReport.AvailabilityReport.AvailabilityStatus.Available) &&
report.FrameFilters.All(f => f.Availability == SessionReport.AvailabilityReport.AvailabilityStatus.Available))
{
Session.AssembleUpdate -= OnAssembleUpdate;
// компоненты session доступны на текущем устройстве, можно запускать session
Session.StartSession();
}
else
{
// компоненты session недоступны на текущем устройстве
}
if (report.PendingDeviceList.Count <= 0)
{
Session.AssembleUpdate -= OnAssembleUpdate;
}
}
Обратите внимание, что событие AssembleUpdate может сработать дважды. В примере выше подписка отменяется после подтверждения доступности компонентов.
Этот метод не позволяет определить другие ошибки, которые могут возникнуть при запуске session, но такие ошибки обычно не зависят от устройства. При необходимости можно дополнить проверку после запуска через событие StateChanged.
Что делать, если компоненты session недоступны
В разработке приложений обычно хотят поддерживать как можно больше устройств. Когда компоненты session недоступны на текущем устройстве, можно рассмотреть следующие варианты:
Понизить до других AR-функций
Измените конфигурацию компонентов session и выберите AR-функции, поддерживаемые текущим устройством. См. создать session, чтобы узнать, как менять конфигурацию.Предоставить не-AR опыт
Когда компоненты session недоступны, можно предложить опыт без AR. Например, в сценарии навигации, если AR-навигация невозможна, традиционная 2D-навигация очень полезна.Предложить пользователю сменить устройство
В некоторых сценариях пользователь может использовать устройство, не поддерживающее AR-функции. Тогда можно предложить сменить устройство для лучшего опыта.
При выборе этих вариантов учитывайте требования приложения и целевую аудиторию. В AR-приложении, если некоторые устройства действительно не могут предоставить AR или вариант с понижением, всё равно важно показать пользователю хорошее сообщение, чтобы он понял ограничения устройства.
Следующие шаги
- Узнайте, как контролировать выполнение session
- Узнайте источник кадров и выбор во время выполнения
- Также можно посмотреть следующие примеры, чтобы понять сценарии после получения отчёта:
- пример Workflow_ARSession использует событие StateChanged и показывает UI для состояния Broken, а также использует AssembleUpdate для отображения доступности каждого компонента в UI
- Пример SpatialMap_Sparse_AllInOne использует AssembleUpdate для предварительной проверки поддержки устройства и вывода предупреждения, если она недоступна
- Пример MotionTracking_DeviceMotionAndPlaneDetection использует событие StateChanged и показывает UI для состояния Broken
- Пример MegaBlock_Basic использует событие StateChanged и показывает UI для состояния Broken