Table of Contents

Acceso a los componentes de funcionalidad AR en la sesión

En una sesión en ejecución, puede acceder a los componentes de funcionalidad individuales a través de la propiedad Assembly. Este artículo describe cómo acceder a estos componentes y las consideraciones a tener en cuenta al hacerlo.

Antes de comenzar

Configurar componentes AR durante la edición o antes de iniciar

A veces, ciertas opciones de componentes (como DesiredFocusMode) deben configurarse antes de iniciar el componente. Si no deseas configurar e iniciar manualmente el componente después de iniciar la sesión, un método sencillo es configurar todos los componentes de fuente de fotogramas potencialmente utilizados antes de ensamblar la sesión. El proceso de ensamblaje conservará uno o más de estos componentes y aplicará su configuración.

En este caso, puedes usar cualquier método básico de Unity como FindAnyObjectByType<T>() o GetComponent<T>() para encontrar los componentes y luego configurarlos.

Nota

Es incierto si los componentes AR obtenidos de esta manera se incluirán en la sesión durante el tiempo de ejecución. Por lo tanto, es necesario configurar todos los casos posibles.

Por ejemplo, el siguiente código muestra cómo modificar el modo de enfoque de todos los componentes de fuente de fotogramas antes de ensamblar la sesión:

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;
        }
    }
}

Este proceso también se puede realizar en el editor, configurando igualmente todos los componentes:

texto alternativo

Las configuraciones para las dos fuentes de fotogramas ARCoreARFoundationFrameSource y ARKitARFoundationFrameSource se encuentran en el componente de la Main Camera.

Advertencia

Los componentes AR obtenidos de esta manera solo deben usarse para la configuración previa a la ejecución.
Debido a que el proceso de ensamblaje filtra los componentes AR, los componentes AR obtenidos a través de la jerarquía de la escena podrían no estar incluidos en la sesión y no funcionarán correctamente.

Uso de componentes AR ensamblados en tiempo de ejecución

Los componentes AR ejecutados en la sesión se determinan después del ensamblaje. Ningún componente AR puede utilizarse antes de completar el ensamblaje. Los componentes AR ensamblados se pueden acceder a través de la propiedad Assembly.

Assembly está disponible cuando el estado de la sesión es >= Assembled. Específicamente, la propiedad Assembly se asigna después de que se ejecute el método Assemble(), permitiendo acceder a los componentes de la sesión. Cuando la sesión se detiene o se daña, la propiedad Assembly se borra y ya no se puede acceder a los componentes.

Puedes verificar el State de la sesión en un script para determinar cuándo se puede acceder a los componentes AR:

if (Session.State >= ARSession.SessionState.Ready)
{
    // Assembly está disponible
}
else
{
    // Assembly no está disponible
}

También puedes suscribirte al evento StateChanged para capturar cambios de estado de la sesión y acceder a los componentes AR en el momento adecuado. Generalmente, para capturar el estado Ready, debes suscribirte al evento StateChanged antes de iniciar la sesión. Suscribirte en Awake() suele ser seguro:

void Awake()
{
    Session.StateChanged += (state) =>
    {
        if (Session.State == ARSession.SessionState.Ready)
        {
            // Assembly está disponible. Después de esto, Assembly permanece accesible hasta que la sesión se detenga o se dañe.
        }
        else if (Session.State < ARSession.SessionState.Ready)
        {
            // Assembly no está disponible. Después de esto, Assembly permanece inaccesible hasta que la sesión se reinicie.
        }
        else
        {
            // Assembly está disponible, generalmente no requiere manejo adicional.
        }
    };
}
Precaución

Si obtienes componentes AR mediante métodos como FindAnyObjectByType<T>() o GetComponent<T>(), estos definitivamente estarán incluidos en la sesión y pueden usarse en tiempo de ejecución.
Almacenar referencias a estos componentes es seguro, pero al usarlos debes asegurarte de que la sesión esté activa y que los componentes estén correctamente incluidos. De lo contrario, podrían ocurrir excepciones o comportamientos inesperados.
Estos componentes no funcionan antes de iniciar o después de detener la sesión. Se recomienda, incluso con este enfoque, monitorear el State de la sesión y el evento StateChanged.

Acceder al componente de fuente de fotograma

Se puede acceder al componente de fuente de fotograma usando la propiedad ARAssembly.FrameSource. En una sesión en funcionamiento normal, hay exactamente una instancia de ARAssembly.FrameSource.

Al usar la sesión, a menudo necesitas acceder a ARAssembly.FrameSource para determinar qué tipo de fuente de fotograma se está utilizando realmente en tiempo de ejecución, y así acceder a las propiedades y métodos específicos de ese componente.

Por ejemplo, el siguiente código muestra cómo usar diferentes métodos de detección de planos según la fuente de fotograma:

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;
        }
    }
}

Acceder al componente frame filter

El componente frame filter puede ser accedido usando la propiedad ARAssembly.FrameFilters. En una sesión operativa normal, podrían existir múltiples componentes de cualquier tipo presente en la lista ARAssembly.FrameFilters.

Por ejemplo, el siguiente código muestra cómo obtener un MegaTrackerFrameFilter de la sesión y registrar su evento correspondiente:

var megaTracker = session.Assembly.FrameFilters.Where(f => f is MegaTrackerFrameFilter).FirstOrDefault() as MegaTrackerFrameFilter;
if (megaTracker)
{
    megaTracker.LocalizationRespond += (response) =>
    {
    };
}

Acceder al componente de cámara

Puedes usar la propiedad ARAssembly.Camera para acceder al componente de cámara. Es una forma rápida de encontrar la cámara utilizada en AR cuando hay múltiples cámaras en la escena.

Por ejemplo, el siguiente código muestra cómo obtener la cámara en la sesión y realizar una detección por rayo en objetos de la escena:

var ray = Session.Assembly.Camera.ScreenPointToRay(screenPoint);
if (Physics.Raycast(ray, out var hitInfo))
{
    TouchRoot.transform.position = hitInfo.point;
};

Acceder al componente origin

Puedes usar la propiedad ARAssembly.Origin para acceder al componente origin.

Por ejemplo, el siguiente código muestra cómo obtener el origin de la sesión y mostrar un cono que representa la posición y orientación actual de la cámara en la escena:

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);
}

Es importante notar que primero se debe verificar si ARAssembly.Origin existe.

Nota

ARAssembly.Origin solo existe en sesiones con la función de seguimiento de movimiento habilitada.

Acceso a cameraImageRenderer componente

Se puede usar la propiedad ARAssembly.CameraImageRenderer para acceder al componente CameraImageRenderer.

Por ejemplo, el siguiente código obtiene la RenderTexture de la imagen de la cámara física:

RenderTexture renderTexture;

void Awake()
{
    Session.StateChanged += (state) =>
    {
        if (state == ARSession.SessionState.Ready && Session.Assembly.CameraImageRenderer.OnSome)
        {
            Session.Assembly.CameraImageRenderer.Value.RequestTargetTexture((_, texture) => renderTexture = texture);
        }
    };
}

Es importante notar que primero se debe verificar si ARAssembly.CameraImageRenderer existe.

Nota

ARAssembly.CameraImageRenderer solo es válido en sesiones donde la renderización es realizada por EasyAR. Generalmente, es inválido al usar AR Foundation o dispositivos de visualización montados en la cabeza (HMD), donde la renderización de la cámara física la realizan AR Foundation o el SDK del dispositivo.

Acceso al componente framerecorder

Se puede acceder al componente FrameRecorder usando la propiedad ARAssembly.FrameRecorder.

Por ejemplo, el siguiente código inicia la grabación. La ubicación del archivo depende de la configuración y, por defecto, se almacena en el directorio de almacenamiento interno de la aplicación:

if (session.Assembly.FrameRecorder.OnSome)
{
    var frameRecorder = session.Assembly.FrameRecorder.Value;
    frameRecorder.enabled = true;
}

Es importante tener en cuenta que primero se debe verificar si ARAssembly.FrameRecorder existe.

Nota

ARAssembly.FrameRecorder no está disponible en algunos casos, como cuando se utiliza FramePlayer.

Próximos pasos

  • Aprenda cómo obtener resultados de la sesión, que incluyen las salidas de ejecución de los componentes de AR
  • Además, puede explorar estos ejemplos para comprender el acceso a los componentes:
    • El ejemplo Workflow_ARSession demuestra métodos para acceder y utilizar diversos componentes

Temas relacionados