Acessar componentes de função AR na session
Em uma session em execução, é possível acessar cada componente funcional pela propriedade Assembly. Este artigo apresenta como acessar esses componentes e os pontos que exigem atenção durante o acesso.
Antes de começar
- Entenda os conceitos básicos, a composição e o fluxo de trabalho da session em Introdução ao ARSession
- Saiba como criar uma session
Configurar componentes AR durante a edição ou antes da inicialização
Às vezes, certas opções de componente, como DesiredFocusMode, precisam ser configuradas antes que o componente seja iniciado. Se você não quiser configurar e iniciar manualmente os componentes após a inicialização da session, uma forma simples é configurar todas as componentes frame source que possivelmente serão usadas antes da montagem da session. O processo de montagem manterá uma ou mais dessas componentes e aplicará suas configurações.
Nesse momento, é possível usar qualquer método básico do Unity, como FindAnyObjectByType<T>() ou GetComponent<T>(), para encontrar os componentes e então configurá-los.
Nota
Não é certo se os componentes AR obtidos por esse método serão incluídos na session em tempo de execução. Portanto, é necessário configurar todos os casos possíveis.
Por exemplo, o código abaixo mostra o processo de modificar o modo de foco de todos os componentes frame source antes da montagem da 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;
}
}
}
O processo acima também pode ser concluído no editor, e da mesma forma é necessário configurar todos os componentes:

As configurações correspondentes aos dois frame sources ARCoreARFoundationFrameSource e ARKitARFoundationFrameSource ficam nos componentes da Main Camera.
Aviso
Os componentes AR obtidos por esse método só podem ser usados para configuração antes da execução.
Como o processo de montagem filtra os componentes AR, os componentes AR obtidos pela árvore da cena podem não estar incluídos na session e não funcionar corretamente.
Usar componentes AR montados durante a execução
Os componentes AR que rodam na session só são determinados depois da montagem. Antes que a montagem seja concluída, nenhum componente AR pode ser usado. Os componentes AR montados podem ser acessados pela propriedade Assembly.
Assembly pode ser usado quando o estado da session for >= Assembled. Em detalhes, a propriedade Assembly só será atribuída depois que o método Assemble() terminar sua execução, e então ela poderá ser usada para acessar os componentes da session. Depois que a session parar ou quebrar, a propriedade Assembly será limpa e os componentes não poderão mais ser acessados.
É possível verificar State da session no script para determinar se os componentes AR podem ser acessados naquele momento:
if (Session.State >= ARSession.SessionState.Ready)
{
// Assembly esta disponivel
}
else
{
// Assembly nao esta disponivel
}
Também é possível assinar o evento StateChanged para obter mudanças de estado da session e acessar os componentes AR no momento adequado. Em geral, para capturar o estado Ready, é necessário assinar o evento StateChanged antes do início da session; normalmente, assinar em Awake() é seguro:
void Awake()
{
Session.StateChanged += (state) =>
{
if (Session.State == ARSession.SessionState.Ready)
{
// Assembly esta disponivel; depois disso, Assembly permanece acessivel ate que a session seja interrompida ou danificada
}
else if (Session.State < ARSession.SessionState.Ready)
{
// Assembly nao esta disponivel; depois disso, Assembly permanece inacessivel ate que a session seja reiniciada
}
else
{
// Assembly esta disponivel; normalmente nao precisa ser tratado
}
};
}
Cuidado
Se os componentes AR obtidos por métodos como FindAnyObjectByType<T>() ou GetComponent<T>() certamente forem incluídos na session, eles também poderão ser usados em tempo de execução.
Apenas armazenar referências a esses componentes é seguro, mas ao usá-los é necessário garantir que a session esteja em execução e que esses componentes estejam corretamente incluídos na session; caso contrário, exceções ou comportamentos inesperados podem ocorrer.
Antes da session iniciar e depois de parar, esses componentes não funcionam. Recomenda-se que, mesmo nesse tipo de uso, você acompanhe State e o evento StateChanged da session.
Acessar componentes frame source
É possível acessar o componente frame source pela propriedade ARAssembly.FrameSource. Em uma session funcionando normalmente, existe um e somente um ARAssembly.FrameSource.
Ao usar a session, normalmente é necessário acessar ARAssembly.FrameSource para determinar o tipo de componente frame source realmente usado em tempo de execução e, assim, acessar propriedades e métodos específicos desse componente.
Por exemplo, o código abaixo mostra como usar diferentes métodos de detecção de plano de acordo com o 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;
}
}
}
Acessar componentes frame filter
É possível acessar componentes frame filter pela propriedade ARAssembly.FrameFilters. Em uma session funcionando normalmente, qualquer tipo de componente na lista ARAssembly.FrameFilters pode ter várias instâncias.
Por exemplo, o código abaixo mostra como obter um MegaTrackerFrameFilter da session e registrar o evento correspondente:
var megaTracker = session.Assembly.FrameFilters.Where(f => f is MegaTrackerFrameFilter).FirstOrDefault() as MegaTrackerFrameFilter;
if (megaTracker)
{
megaTracker.LocalizationRespond += (response) =>
{
};
}
Acessar componente camera
É possível acessar o componente camera pela propriedade ARAssembly.Camera. Se houver várias cameras na cena, esta é uma forma rápida de encontrar a câmera usada por AR.
Por exemplo, o código abaixo mostra como obter a camera da session e fazer raycast em objetos da cena:
var ray = Session.Assembly.Camera.ScreenPointToRay(screenPoint);
if (Physics.Raycast(ray, out var hitInfo))
{
TouchRoot.transform.position = hitInfo.point;
};
Acessar componente origin
É possível acessar o componente origin pela propriedade ARAssembly.Origin.
Por exemplo, o código abaixo mostra como obter o origin da session e exibir na cena um cone que representa a posição e a orientação atuais da câmera:
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);
}
Observe que aqui é necessário primeiro verificar se ARAssembly.Origin existe.
Nota
ARAssembly.Origin só existe em sessions com rastreamento de movimento habilitado.
Acessar componente CameraImageRenderer
É possível acessar o componente CameraImageRenderer pela propriedade ARAssembly.CameraImageRenderer.
Por exemplo, o código abaixo pode obter a RenderTexture da imagem da câmera 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);
}
};
}
Observe que aqui é necessário primeiro verificar se ARAssembly.CameraImageRenderer existe.
Nota
ARAssembly.CameraImageRenderer só é válido em sessions cuja imagem é desenhada pelo EasyAR. Em geral, ao usar AR Foundation ou headsets, ele é inválido; nesse caso, a imagem da câmera física é desenhada pelo AR Foundation ou pelo SDK do headset.
Acessar componente FrameRecorder
É possível acessar o componente FrameRecorder pela propriedade ARAssembly.FrameRecorder.
Por exemplo, o código abaixo pode iniciar a gravação; o local de armazenamento do arquivo depende da configuração e, por padrão, ele será armazenado no diretório interno do aplicativo:
if (session.Assembly.FrameRecorder.OnSome)
{
var frameRecorder = session.Assembly.FrameRecorder.Value;
frameRecorder.enabled = true;
}
Observe que aqui é necessário primeiro verificar se ARAssembly.FrameRecorder existe.
Nota
ARAssembly.FrameRecorder não pode ser usado em alguns poucos casos, como ao usar FramePlayer.
Próximos passos
- Saiba como obter os resultados de execução da session, que incluem as saídas de execução dos componentes AR
- Além disso, você também pode aprender sobre o acesso a componentes por meio destes exemplos:
- O exemplo Workflow_ARSession mostra os métodos de acesso e uso de diversos componentes
Tópicos relacionados
- Fonte de quadros descreve frame source e o método de seleção em tempo de execução
- XR Origin descreve a finalidade do componente origin na cena AR
- Camera descreve a finalidade do componente camera na cena AR
- Gravar arquivos EIF descreve o uso detalhado de FrameRecorder