Acessar os componentes de funcionalidade AR na session
Durante uma session em execução, você pode acessar os vários componentes de funcionalidade através da propriedade Assembly. Este artigo descreve como acessar esses componentes e as considerações importantes ao fazê-lo.
Antes de começar
- Familiarize-se com os conceitos básicos, composição e fluxo de trabalho de uma sessão através da Introdução ao ARSession
- Saiba como criar uma sessão
Configurar componentes AR durante a edição ou antes da inicialização
Algumas vezes, certas opções de componente (como DesiredFocusMode) precisam ser configuradas antes da inicialização do componente. Se não quiser configurar e iniciar manualmente o componente após o início da sessão, um método simples é configurar todos os componentes de origem de quadro potencialmente usados antes da montagem da sessão. O processo de montagem manterá um ou mais desses componentes e aplicará suas configurações.
Nesse caso, você pode usar métodos básicos do Unity como FindAnyObjectByType<T>() ou GetComponent<T>() para localizar o componente e, em seguida, configurá-lo.
Nota
Não é certo se os componentes AR obtidos por esse método serão incluídos na sessão durante o tempo de execução. Portanto, todas as possibilidades devem ser configuradas.
Por exemplo, o código abaixo mostra o processo de modificar o modo de foco de todos os componentes de origem de quadro antes da montagem da sessão:
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 processo também pode ser realizado no editor, exigindo configuração para todos os componentes:

A configuração correspondente às duas origens de quadro ARCoreARFoundationFrameSource e ARKitARFoundationFrameSource está no componente da Main Camera.
Aviso
Os componentes AR obtidos por esse método só devem ser usados para configuração pré-execução.
Como o processo de montagem filtra os componentes AR, os componentes AR obtidos através da hierarquia de cena podem não estar incluídos na sessão e não funcionarão corretamente.
Utilizando componentes AR montados durante a execução
Os componentes AR executados dentro de uma sessão são determinados após a montagem. Nenhum componente AR pode ser utilizado antes da montagem estar completa. Os componentes AR montados podem ser acessados através da propriedade Assembly.
Assembly está disponível quando o estado da sessão é >= Assembled. Especificamente, a propriedade Assembly só é atribuída após a conclusão do método Assemble(), permitindo o acesso aos componentes da sessão através dela. Após a sessão ser parada ou corrompida, a propriedade Assembly é limpa, tornando os componentes inacessíveis.
Você pode verificar o State da sessão em um script para determinar se os componentes AR podem ser acessados naquele momento:
if (Session.State >= ARSession.SessionState.Ready)
{
// Assembly pode ser utilizado
}
else
{
// Assembly não pode ser utilizado
}
Alternativamente, você pode se inscrever no evento StateChanged para receber notificações sobre mudanças no estado da sessão, permitindo acessar os componentes AR no momento apropriado. Geralmente, para capturar o estado Ready, é necessário se inscrever no evento StateChanged antes do início da sessão. Fazer a inscrição dentro de Awake() geralmente é seguro:
void Awake()
{
Session.StateChanged += (state) =>
{
if (Session.State == ARSession.SessionState.Ready)
{
// Assembly pode ser utilizado. Após este ponto, o Assembly permanece acessível até a sessão ser parada ou corrompida.
}
else if (Session.State < ARSession.SessionState.Ready)
{
// Assembly não pode ser utilizado. Após este ponto, o Assembly permanece inacessível até a sessão ser reiniciada.
}
else
{
// Assembly pode ser utilizado. Normalmente não requer tratamento.
}
};
}
Cuidado
Se você obtiver componentes AR através de métodos como FindAnyObjectByType<T>() ou GetComponent<T>(), eles serão incluídos na sessão e podem ser usados durante a execução.
Armazenar referências a esses componentes é seguro, mas ao utilizá-los, você deve garantir que a sessão esteja em execução e que os componentes estejam corretamente incluídos nela. Caso contrário, podem ocorrer exceções ou comportamentos inesperados.
Esses componentes não funcionam antes da sessão iniciar ou após ser parada. Mesmo usando esta abordagem, é recomendado monitorar o State da sessão e o evento StateChanged.
Acessar componentes de fonte de quadro
É possível acessar componentes de fonte de quadro usando a propriedade ARAssembly.FrameSource. Em uma sessão em funcionamento normal, há exatamente um ARAssembly.FrameSource.
Ao usar a sessão, geralmente é necessário acessar ARAssembly.FrameSource para determinar o tipo real de componente de fonte de quadro usado durante a execução, permitindo assim acessar propriedades e métodos específicos desse componente.
Por exemplo, o código abaixo demonstra como usar métodos diferentes de detecção de plano dependendo da fonte de quadro:
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 o componente frame filter
Você pode acessar os componentes frame filter usando a propriedade ARAssembly.FrameFilters. Em uma sessão em execução normal, qualquer tipo de componente na lista ARAssembly.FrameFilters pode ter vários.
Por exemplo, o código abaixo mostra como obter um MegaTrackerFrameFilter na sessão e registrar o evento correspondente:
var megaTracker = session.Assembly.FrameFilters.Where(f => f is MegaTrackerFrameFilter).FirstOrDefault() as MegaTrackerFrameFilter;
if (megaTracker)
{
megaTracker.LocalizationRespond += (response) =>
{
};
}
Acessar o componente camera
É possível acessar o componente camera usando a propriedade ARAssembly.Camera. Se houver várias câmeras na cena, esta é uma forma rápida de localizar a câmera utilizada para AR.
Por exemplo, o código abaixo mostra como obter a câmera da sessão e realizar a detecção de raio em objetos na cena:
var ray = Session.Assembly.Camera.ScreenPointToRay(screenPoint);
if (Physics.Raycast(ray, out var hitInfo))
{
TouchRoot.transform.position = hitInfo.point;
};
Acessando o componente origin
Pode usar a propriedade ARAssembly.Origin para acessar o componente origin.
Por exemplo, o código abaixo mostra como obter o origin da sessão e exibir um cone representando a posição e orientação atuais da câmera na cena:
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);
}
É importante notar que primeiro é necessário verificar se ARAssembly.Origin existe.
Nota
ARAssembly.Origin existe apenas em sessões com recursos de acompanhamento de movimento ativados.
Acessar o componente CameraImageRenderer
Pode-se usar a propriedade ARAssembly.CameraImageRenderer para acessar o componente CameraImageRenderer.
Por exemplo, o código abaixo obtém 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);
}
};
}
É importante notar que é necessário verificar primeiro se ARAssembly.CameraImageRenderer existe.
Nota
ARAssembly.CameraImageRenderer só é válido em sessões onde o desenho da imagem é feito pelo EasyAR. Geralmente, não é válido ao usar AR Foundation ou headsets, pois o desenho da imagem da câmera física é feito pelo AR Foundation ou pelo SDK do headset.
Acessar o framerecorder componente
O componente FrameRecorder pode ser acessado usando a propriedade ARAssembly.FrameRecorder.
Por exemplo, o seguinte código inicia a gravação. A localização do arquivo depende da configuração, e por padrão é armazenado no diretório de armazenamento interno do aplicativo:
if (session.Assembly.FrameRecorder.OnSome)
{
var frameRecorder = session.Assembly.FrameRecorder.Value;
frameRecorder.enabled = true;
}
Note que é necessário verificar primeiro se ARAssembly.FrameRecorder existe.
Nota
ARAssembly.FrameRecorder não está disponível em alguns casos, como quando se usa o FramePlayer.
Próximos passos
- Saiba como obter os resultados de execução da sessão, que incluem a saída de execução dos componentes AR
- Adicionalmente, você pode explorar o acesso aos componentes através destes exemplos:
- O exemplo Workflow_ARSession demonstra métodos de acesso e utilização de diversos componentes
Tópicos relacionados
- Fonte de dados de quadro (frame source) descreve a fonte de quadro e como selecioná-la durante a execução
- Origem XR (XR Origin) descreve a finalidade do componente de origem em cenas AR
- Câmera (Camera) descreve a finalidade do componente de câmera em cenas AR
- Gravar arquivos EIF (Recording EIF files) descreve o uso detalhado do FrameRecorder