Доступ к компонентам AR-функций в session
В работающей session можно обращаться к различным функциональным компонентам через свойство Assembly. В этой статье описано, как обращаться к этим компонентам и на что нужно обращать внимание при доступе к ним.
Перед началом
- Ознакомьтесь с базовыми понятиями, составом и рабочим процессом session через Введение в ARSession
- Узнайте, как создать session
Настройка AR-компонентов во время редактирования или перед запуском
Иногда некоторые параметры компонентов, например DesiredFocusMode, необходимо настроить до запуска компонента. Если вы не хотите вручную настраивать и запускать компоненты после запуска session, простой способ — настроить все потенциально используемые компоненты frame source перед сборкой session. Процесс сборки сохранит один или несколько из этих компонентов и применит их конфигурацию.
В это время можно использовать любые базовые методы Unity, такие как FindAnyObjectByType<T>() или GetComponent<T>(), чтобы найти компоненты и затем настроить их.
Примечание
Не определено, будут ли AR-компоненты, полученные таким способом, включены в session во время выполнения. Поэтому необходимо настроить все возможные варианты.
Например, следующий код показывает процесс изменения режима фокусировки для всех компонентов frame source перед сборкой session:
void Awake()
{
var allFrameSources = Session.GetComponentsInChildren<FrameSource>();
foreach (var source in allFrameSources)
{
if (source is CameraDeviceFrameSource)
{
((CameraDeviceFrameSource)source).DesiredFocusMode = autoFocus ? CameraDeviceFocusMode.Continousauto : CameraDeviceFocusMode.Medium;
}
else if (source is MotionTrackerFrameSource)
{
((MotionTrackerFrameSource)source).DesiredFocusMode = autoFocus ? MotionTrackerCameraDeviceFocusMode.Continousauto : MotionTrackerCameraDeviceFocusMode.Medium;
}
else if (source is ARCoreFrameSource)
{
((ARCoreFrameSource)source).DesiredFocusMode = autoFocus ? ARCoreCameraDeviceFocusMode.Auto : ARCoreCameraDeviceFocusMode.Fixed;
}
else if (source is ARKitFrameSource)
{
((ARKitFrameSource)source).DesiredFocusMode = autoFocus ? ARKitCameraDeviceFocusMode.Auto : ARKitCameraDeviceFocusMode.Fixed;
}
else if (source is AREngineFrameSource)
{
((AREngineFrameSource)source).DesiredFocusMode = autoFocus ? AREngineCameraDeviceFocusMode.Auto : AREngineCameraDeviceFocusMode.Fixed;
}
else if (source is ThreeDofCameraDeviceFrameSource)
{
((ThreeDofCameraDeviceFrameSource)source).DesiredFocusMode = autoFocus ? ThreeDofCameraDeviceFocusMode.Auto : ThreeDofCameraDeviceFocusMode.Fixed;
}
else if (source is InertialCameraDeviceFrameSource)
{
((InertialCameraDeviceFrameSource)source).DesiredFocusMode = autoFocus ? InertialCameraDeviceFocusMode.Auto : InertialCameraDeviceFocusMode.Fixed;
}
else if (source is ARFoundationFrameSource)
{
cameraManager.autoFocusRequested = autoFocus;
}
}
}
Этот процесс также можно выполнить в редакторе; при этом также нужно настроить все компоненты:

Конфигурация двух frame source, ARCoreARFoundationFrameSource и ARKitARFoundationFrameSource, находится на компоненте Main Camera.
Предупреждение
AR-компоненты, полученные таким способом, можно использовать только для настройки перед запуском.
Поскольку процесс сборки отбирает AR-компоненты, AR-компоненты, полученные через дерево сцены, могут не быть включены в session и не смогут работать нормально.
Использование собранных AR-компонентов во время выполнения
AR-компоненты, работающие в session, определяются только после сборки. До завершения сборки никакие AR-компоненты использовать нельзя. Собранные AR-компоненты доступны через свойство Assembly.
Assembly можно использовать при условии, что состояние session >= Assembled. В частности, свойство Assembly получает значение только после завершения выполнения метода Assemble(); через него можно обращаться к компонентам session. После остановки или повреждения session свойство Assembly очищается, и доступ к компонентам становится невозможен.
В скрипте можно проверять State session, чтобы определить, можно ли в этот момент обращаться к AR-компонентам:
if (Session.State >= ARSession.SessionState.Ready)
{
// Assembly доступна
}
else
{
// Assembly недоступна
}
Также можно подписаться на событие StateChanged, чтобы получать изменения состояния session и обращаться к AR-компонентам в подходящий момент. В целом, чтобы успеть поймать состояние Ready, нужно подписаться на событие StateChanged до start session; обычно безопасно выполнить подписку в Awake():
void Awake()
{
Session.StateChanged += (state) =>
{
if (Session.State == ARSession.SessionState.Ready)
{
// Assembly доступна; после этого Assembly остается доступной, пока session не остановится или не будет повреждена
}
else if (Session.State < ARSession.SessionState.Ready)
{
// Assembly недоступна; после этого Assembly остается недоступной, пока session не будет перезапущена
}
else
{
// Assembly доступна; обычно обработка не требуется
}
};
}
Осторожно
Если AR-компоненты, полученные через FindAnyObjectByType<T>() или GetComponent<T>() и другие методы, гарантированно будут включены в session, их также можно использовать во время выполнения.
Хранить ссылки на эти компоненты безопасно, но при использовании этих компонентов нужно убедиться, что session находится в рабочем состоянии и эти компоненты корректно включены в session; иначе могут возникнуть исключения или непредсказуемое поведение.
До запуска session и после ее остановки эти компоненты не работают. Даже при таком использовании рекомендуется следить за State session и событием StateChanged.
Доступ к компоненту frame source
К компоненту frame source можно обращаться через свойство ARAssembly.FrameSource. В нормально работающей session ARAssembly.FrameSource существует ровно один.
При использовании session обычно нужно обратиться к ARAssembly.FrameSource, чтобы определить фактический тип компонента frame source, используемый во время выполнения, и затем получить доступ к свойственным этому компоненту свойствам и методам.
Например, следующий код показывает, как использовать разные методы обнаружения плоскости в зависимости от frame source:
void PlaceObject(Vector2 touchPosition)
{
if (Session.Assembly.FrameSource is MotionTrackerFrameSource)
{
Ray ray = Session.Assembly.Camera.ScreenPointToRay(touchPosition);
if (Physics.Raycast(ray, out var hitInfo))
{
TouchRoot.transform.position = hitInfo.point;
}
}
else if (Session.Assembly.FrameSource is ARFoundationFrameSource)
{
var raycastManager = Session.Assembly.Origin.Value.GetComponent<UnityEngine.XR.ARFoundation.ARRaycastManager>();
var hits = new List<UnityEngine.XR.ARFoundation.ARRaycastHit>();
if (raycastManager.Raycast(touchPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon))
{
var hitPose = hits[0].pose;
TouchRoot.transform.position = hitPose.position;
}
}
}
Доступ к компонентам frame filter
К компонентам frame filter можно обращаться через свойство ARAssembly.FrameFilters. В нормально работающей session в списке ARAssembly.FrameFilters компонентов любого типа может быть несколько.
Например, следующий код показывает, как получить один MegaTrackerFrameFilter из session и зарегистрировать соответствующее событие:
var megaTracker = session.Assembly.FrameFilters.Where(f => f is MegaTrackerFrameFilter).FirstOrDefault() as MegaTrackerFrameFilter;
if (megaTracker)
{
megaTracker.LocalizationRespond += (response) =>
{
};
}
Доступ к компоненту camera
К компоненту camera можно обращаться через свойство ARAssembly.Camera. Если в сцене несколько camera, это быстрый способ найти камеру, используемую AR.
Например, следующий код показывает, как получить camera в session и выполнить raycast объектов в сцене:
var ray = Session.Assembly.Camera.ScreenPointToRay(screenPoint);
if (Physics.Raycast(ray, out var hitInfo))
{
TouchRoot.transform.position = hitInfo.point;
};
Доступ к компоненту origin
К компоненту origin можно обращаться через свойство ARAssembly.Origin.
Например, следующий код показывает, как получить origin в session и отобразить в сцене усеченную пирамиду, представляющую текущее положение и ориентацию камеры:
if (session.Assembly.Origin.OnSome)
{
GameObject frustum = Instantiate(CameraFrustumPrefab, session.Assembly.Camera.transform.position, session.Assembly.Camera.transform.rotation);
frustum.transform.SetParent(session.Assembly.Origin.Value.transform);
}
Обратите внимание: здесь сначала нужно проверить, существует ли ARAssembly.Origin.
Примечание
ARAssembly.Origin существует только в session, где включена функция отслеживания движения.
Доступ к компоненту CameraImageRenderer
К компоненту CameraImageRenderer можно обращаться через свойство ARAssembly.CameraImageRenderer.
Например, следующий код получает RenderTexture изображения физической камеры:
RenderTexture renderTexture;
void Awake()
{
Session.StateChanged += (state) =>
{
if (state == ARSession.SessionState.Ready && Session.Assembly.CameraImageRenderer.OnSome)
{
Session.Assembly.CameraImageRenderer.Value.RequestTargetTexture((_, texture) => renderTexture = texture);
}
};
}
Обратите внимание: здесь сначала нужно проверить, существует ли ARAssembly.CameraImageRenderer.
Примечание
ARAssembly.CameraImageRenderer действует только в session, где отрисовку изображения выполняет EasyAR. Как правило, при использовании AR Foundation или головных дисплеев он недействителен; в этом случае отрисовка изображения физической камеры выполняется AR Foundation или SDK головного дисплея.
Доступ к компоненту FrameRecorder
К компоненту FrameRecorder можно обращаться через свойство ARAssembly.FrameRecorder.
Например, следующий код запускает запись; место сохранения файла зависит от конфигурации, по умолчанию он сохраняется во внутреннем каталоге хранения приложения:
if (session.Assembly.FrameRecorder.OnSome)
{
var frameRecorder = session.Assembly.FrameRecorder.Value;
frameRecorder.enabled = true;
}
Обратите внимание: здесь сначала нужно проверить, существует ли ARAssembly.FrameRecorder.
Примечание
ARAssembly.FrameRecorder в некоторых случаях, например при использовании FramePlayer, недоступен.
Дальнейшие шаги
- Узнайте, как получать результаты работы session; эти результаты содержат выходные данные AR-компонентов
- Кроме того, вы можете изучить доступ к компонентам по следующим примерам:
- Пример Workflow_ARSession показывает способы доступа к различным компонентам и их использования
Связанные темы
- Источник данных кадров описывает frame source и способ выбора во время выполнения
- XR Origin описывает назначение компонента origin в AR-сцене
- Camera описывает назначение компонента camera в AR-сцене
- Запись EIF-файлов описывает подробное использование FrameRecorder