Acceder a los componentes de funciones AR en una session
En una session en ejecucion, puede acceder a los distintos componentes de funciones mediante la propiedad Assembly. Este articulo presenta como acceder a estos componentes y las consideraciones que debe tener en cuenta al hacerlo.
Antes de empezar
- Conozca los conceptos basicos, la composicion y el flujo de trabajo de la session mediante Introduccion a ARSession
- Aprenda como crear una session
Configurar componentes AR durante la edicion o antes del inicio
En algunos casos, ciertas opciones de componentes, como DesiredFocusMode, deben configurarse antes de que el componente se inicie. Si no desea configurar e iniciar manualmente los componentes despues de que se inicie la session, una forma sencilla es configurar todos los componentes frame source que puedan usarse antes del ensamblaje de la session. El proceso de ensamblaje conservara uno o varios de estos componentes y aplicara su configuracion.
En este momento puede usar cualquier metodo basico de Unity, como FindAnyObjectByType<T>() o GetComponent<T>(), para encontrar los componentes y configurarlos.
Nota
No es seguro que los componentes AR obtenidos mediante este metodo se incluyan en la session durante la ejecucion. Por lo tanto, debe configurar todas las posibilidades.
Por ejemplo, el codigo siguiente muestra el proceso de modificar el modo de enfoque de todos los componentes frame source antes del ensamblaje de la 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;
}
}
}
El proceso anterior tambien se puede completar en el editor, y del mismo modo debe configurar todos los componentes:

La configuracion correspondiente a los dos frame source ARCoreARFoundationFrameSource y ARKitARFoundationFrameSource esta en el componente de Main Camera.
Advertencia
Los componentes AR obtenidos mediante este metodo solo pueden usarse para configuracion previa a la ejecucion.
Como el proceso de ensamblaje filtra los componentes AR, los componentes AR obtenidos desde el arbol de escena pueden no estar incluidos en la session y no funcionar correctamente.
Usar componentes AR ensamblados durante la ejecucion
Los componentes AR que se ejecutan en la session solo se determinan despues del ensamblaje. Antes de que el ensamblaje termine, ningun componente AR puede usarse. Los componentes AR ensamblados se pueden acceder mediante la propiedad Assembly.
Assembly se puede usar cuando el estado de la session es >= Assembled. En detalle, la propiedad Assembly solo recibe valor despues de que el metodo Assemble() termina, y entonces puede usarse para acceder a los componentes de la session. Despues de que la session se detenga o se rompa, la propiedad Assembly se limpia y ya no se puede acceder a los componentes.
Puede comprobar State de la session en un script para determinar si en ese momento se puede acceder a los componentes AR:
if (Session.State >= ARSession.SessionState.Ready)
{
// Assembly esta disponible
}
else
{
// Assembly no esta disponible
}
Tambien puede suscribirse al evento StateChanged para obtener cambios de estado de la session y acceder a los componentes AR en el momento adecuado. En general, para poder capturar el estado Ready, debe suscribirse al evento StateChanged antes del inicio de la session; normalmente es seguro completar la suscripcion en Awake():
void Awake()
{
Session.StateChanged += (state) =>
{
if (Session.State == ARSession.SessionState.Ready)
{
// Assembly esta disponible; despues de esto, Assembly permanece accesible hasta que la session se detenga o se dane
}
else if (Session.State < ARSession.SessionState.Ready)
{
// Assembly no esta disponible; despues de esto, Assembly permanece inaccesible hasta que la session se reinicie
}
else
{
// Assembly esta disponible; normalmente no requiere gestion
}
};
}
Precaución
Si los componentes AR obtenidos mediante FindAnyObjectByType<T>() o GetComponent<T>() se sabe con certeza que se incluiran en la session, tambien pueden usarse durante la ejecucion.
Guardar referencias a estos componentes es seguro, pero al usarlos debe asegurarse de que la session este en ejecucion y de que estos componentes esten correctamente incluidos en la session; de lo contrario, pueden producirse excepciones o comportamientos inesperados.
Antes de iniciar la session y despues de detenerla, estos componentes no pueden funcionar. Incluso en este uso, se recomienda prestar atencion a State y al evento StateChanged de la session.
Acceder a componentes frame source
Puede usar la propiedad ARAssembly.FrameSource para acceder al componente frame source. En una session que se ejecuta normalmente, hay uno y solo un ARAssembly.FrameSource.
Al usar una session, normalmente debe acceder a ARAssembly.FrameSource para determinar el tipo de componente frame source que se usa realmente en tiempo de ejecucion, y asi acceder a las propiedades y metodos especificos de ese componente.
Por ejemplo, el codigo siguiente muestra como usar distintos metodos de deteccion de planos segun el 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;
}
}
}
Acceder a componentes frame filter
Puede usar la propiedad ARAssembly.FrameFilters para acceder a los componentes frame filter. En una session que se ejecuta normalmente, puede haber varios componentes de cualquier tipo en la lista ARAssembly.FrameFilters.
Por ejemplo, el codigo siguiente muestra como obtener un MegaTrackerFrameFilter en la session y registrar el evento correspondiente:
var megaTracker = session.Assembly.FrameFilters.Where(f => f is MegaTrackerFrameFilter).FirstOrDefault() as MegaTrackerFrameFilter;
if (megaTracker)
{
megaTracker.LocalizationRespond += (response) =>
{
};
}
Acceder al componente camera
Puede usar la propiedad ARAssembly.Camera para acceder al componente camera. Si hay varias cameras en la escena, esta es una forma rapida de encontrar la camara usada por AR.
Por ejemplo, el codigo siguiente muestra como obtener la camera de la session y realizar un raycast sobre 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
Puede usar la propiedad ARAssembly.Origin para acceder al componente origin.
Por ejemplo, el codigo siguiente muestra como obtener el origin de la session y mostrar en la escena un frustum que representa la posicion y orientacion actuales de la camara:
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);
}
Debe tener en cuenta que aqui primero debe comprobar si ARAssembly.Origin existe.
Nota
ARAssembly.Origin solo existe en sessions con seguimiento de movimiento habilitado.
Acceder al componente CameraImageRenderer
Puede usar la propiedad ARAssembly.CameraImageRenderer para acceder al componente CameraImageRenderer.
Por ejemplo, este codigo puede obtener el RenderTexture de la imagen de la camara fisica:
RenderTexture renderTexture;
void Awake()
{
Session.StateChanged += (state) =>
{
if (state == ARSession.SessionState.Ready && Session.Assembly.CameraImageRenderer.OnSome)
{
Session.Assembly.CameraImageRenderer.Value.RequestTargetTexture((_, texture) => renderTexture = texture);
}
};
}
Debe tener en cuenta que aqui primero debe comprobar si ARAssembly.CameraImageRenderer existe.
Nota
ARAssembly.CameraImageRenderer solo es valido en sessions en las que EasyAR realiza el dibujo de la imagen. En general, no es valido al usar AR Foundation o un headset; en ese caso, el dibujo de la imagen de la camara fisica lo realiza AR Foundation o el SDK del headset.
Acceder al componente FrameRecorder
Puede usar la propiedad ARAssembly.FrameRecorder para acceder al componente FrameRecorder.
Por ejemplo, el codigo siguiente puede iniciar la grabacion. La ubicacion de almacenamiento del archivo depende de la configuracion; de forma predeterminada se almacenara en el directorio de almacenamiento interno de la aplicacion:
if (session.Assembly.FrameRecorder.OnSome)
{
var frameRecorder = session.Assembly.FrameRecorder.Value;
frameRecorder.enabled = true;
}
Debe tener en cuenta que aqui primero debe comprobar si ARAssembly.FrameRecorder existe.
Nota
ARAssembly.FrameRecorder no puede usarse en unas pocas situaciones, por ejemplo al usar FramePlayer.
Pasos siguientes
- Aprenda como obtener los resultados de ejecucion de la session, que contienen las salidas de ejecucion de los componentes AR
- Ademas, puede conocer el acceso a componentes mediante los siguientes ejemplos:
- El ejemplo Workflow_ARSession muestra los metodos de acceso y uso de diversos componentes
Temas relacionados
- Fuente de datos de fotogramas describe el frame source y el metodo de seleccion en tiempo de ejecucion
- XR Origin describe el uso del componente origin en una escena AR
- Camera describe el uso del componente camera en una escena AR
- Grabar archivos EIF describe el uso detallado de FrameRecorder