Доступ к ar-компонентам в сеансе
В работающем сеансе можно получить доступ к различным функциональным компонентам через свойство Assembly. В этой статье объясняется, как получить доступ к этим компонентам, а также моменты, на которые следует обратить внимание при доступе.
Перед началом
- Ознакомьтесь с основами сессий через Введение в ARSession, чтобы понять базовые концепции, компоненты и рабочий процесс
- Узнайте, как создать сессию
Настройка компонентов ar во время редактирования или перед запуском
Некоторые параметры компонентов (например DesiredFocusMode) необходимо настраивать до запуска компонента. Если вы не хотите вручную настраивать и запускать компонент после старта сессии, можно заранее настроить все возможные источники кадров перед сборкой сессии. Процесс сборки сохранит один или несколько этих компонентов и применит их конфигурацию.
Для этого используйте любые базовые методы Unity, такие как FindAnyObjectByType<T>() или GetComponent<T>(), чтобы найти компоненты и настроить их.
Примечание
Невозможно гарантировать, что полученные таким образом AR-компоненты будут включены в сессию во время выполнения. Поэтому необходимо настроить все возможные варианты.
Например, этот код изменяет режим фокусировки всех источников кадров перед сборкой сессии:
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;
}
}
}
Эту настройку также можно выполнить в редакторе, конфигурируя все компоненты:

Для источников кадров ARCoreARFoundationFrameSource и ARKitARFoundationFrameSource настройки находятся в компонентах Main Camera.
Предупреждение
AR-компоненты, полученные таким способом, можно использовать только для предварительной конфигурации.
Поскольку процесс сборки фильтрует AR-компоненты, компоненты, полученные из иерархии сцены, могут не входить в сессию и работать некорректно.
Использование собранных AR компонентов во время выполнения
AR компоненты, работающие в сессии, определяются только после сборки. До завершения сборки ни один AR компонент не может быть использован. Собранные AR компоненты доступны через свойство Assembly.
Assembly доступно, когда состояние сессии >= Assembled. Конкретно, свойству Assembly присваивается значение только после выполнения метода Assemble(), и через него можно получить доступ к компонентам сессии. После остановки или повреждения сессии свойство Assembly очищается, и доступ к компонентам теряется.
В скриптах можно проверять State сессии, чтобы определить, доступны ли AR компоненты в данный момент:
if (Session.State >= ARSession.SessionState.Ready)
{
// Assembly доступно
}
else
{
// Assembly недоступно
}
Также можно подписаться на событие StateChanged, чтобы отслеживать изменения состояния сессии и обращаться к AR компонентам в подходящий момент. Обычно, чтобы гарантированно перехватить состояние Ready, подписку на событие StateChanged нужно выполнить до старта сессии. Безопасно сделать это, например, в методе Awake():
void Awake()
{
Session.StateChanged += (state) =>
{
if (Session.State == ARSession.SessionState.Ready)
{
// Assembly доступно. После этого момента Assembly доступно, пока сессия не остановится или не повредится.
}
else if (Session.State < ARSession.SessionState.Ready)
{
// Assembly недоступно. После этого момента Assembly недоступно, пока сессия не перезапустится.
}
else
{
// Assembly доступно. Обычно не требует обработки.
}
};
}
Осторожно
Если получить AR компоненты через методы типа FindAnyObjectByType<T>() или GetComponent<T>(), они гарантированно будут включены в сессию и могут использоваться во время выполнения.
Сохранять ссылки на эти компоненты безопасно, но при их использовании необходимо гарантировать, что сессия активна и эти компоненты корректно включены в сессию. В противном случае возможно возникновение исключений или непредсказуемого поведения.
Эти компоненты не работают до старта и после остановки сессии. Рекомендуется даже при таком подходе отслеживать State сессии и событие StateChanged.
Доступ к компоненту источника кадров
Можно использовать свойство ARAssembly.FrameSource для доступа к компоненту источника кадров. В работающей сессии ARAssembly.FrameSource существует ровно один компонент.
При использовании сессии обычно требуется доступ к ARAssembly.FrameSource, чтобы определить фактически используемый тип компонента источника кадров во время выполнения. Это позволяет получить доступ к специфическим свойствам и методам этого компонента.
Например, следующий код демонстрирует, как использовать различные методы обнаружения плоскостей в зависимости от источника кадров:
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
Доступ к компонентам фильтра кадров можно получить через свойство ARAssembly.FrameFilters. В работающем сеансе, в списке ARAssembly.FrameFilters может присутствовать несколько компонентов любого типа.
Например, следующий код демонстрирует, как получить MegaTrackerFrameFilter в сеансе и зарегистрировать соответствующие события:
var megaTracker = session.Assembly.FrameFilters.Where(f => f is MegaTrackerFrameFilter).FirstOrDefault() as MegaTrackerFrameFilter;
if (megaTracker)
{
megaTracker.LocalizationRespond += (response) =>
{
};
}
Доступ к компоненту camera
Для доступа к компоненту camera можно использовать свойство ARAssembly.Camera. Это быстрый способ найти камеру, используемую в AR, если в сцене присутствуют несколько камер.
Например, следующий код демонстрирует получение камеры из сессии и выполнение проверки пересечения луча с объектами в сцене:
var ray = Session.Assembly.Camera.ScreenPointToRay(screenPoint);
if (Physics.Raycast(ray, out var hitInfo))
{
TouchRoot.transform.position = hitInfo.point;
};
Доступ к компоненту origin
Компонент origin можно получить через свойство ARAssembly.Origin.
Например, следующий код демонстрирует, как получить origin из сессии и отобразить в сцене пирамиду, представляющую текущее положение и ориентацию камеры:
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 существует только в сессиях с включенной функцией отслеживания движений.
Доступ к компоненту 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 действителен только в сессиях, где отрисовка выполняется 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.
Следующие шаги
- Узнайте, как получить результаты выполнения сеанса, которые включают вывод работы компонентов AR
- Дополнительно вы можете изучить доступ к компонентам через следующие примеры:
- Пример Workflow_ARSession демонстрирует доступ к различным компонентам и способы их использования
Связанные темы
- Источники кадров описывает frame source и способы его выбора во время выполнения
- XR Origin описывает назначение компонента origin в AR-сценах
- Камера описывает назначение компонента камеры в AR-сценах
- Запись файлов EIF описывает подробное использование FrameRecorder