Table of Contents

Zugriff auf AR-Funktionskomponenten in einer session

In einer laufenden session können die verschiedenen Funktionskomponenten über die Assembly-Eigenschaft aufgerufen werden. Dieser Artikel erläutert, wie auf diese Komponenten zugegriffen werden kann und welche Punkte dabei zu beachten sind.

Bevor Sie beginnen

Konfiguration von AR-Komponenten zur Bearbeitungszeit oder vor dem Start

Manchmal müssen bestimmte Komponentenoptionen (wie DesiredFocusMode) vor dem Start der Komponente konfiguriert werden. Wenn Sie nicht manuell nach dem Start der Session konfigurieren möchten, können Sie alle potenziell verwendeten Frame-Source-Komponenten vor dem Zusammenbau der Session konfigurieren. Der Zusammenbauprozess behält eine oder mehrere dieser Komponenten bei und wendet deren Konfiguration an.

Hierzu können Sie Unity-Basismethoden wie FindAnyObjectByType<T>() oder GetComponent<T>() verwenden, um die Komponente zu finden und zu konfigurieren.

Anmerkung

Es ist ungewiss, ob auf diese Weise gefundene AR-Komponenten zur Laufzeit in der Session enthalten sind. Daher müssen alle möglichen Fälle konfiguriert werden.

Der folgende Code zeigt beispielsweise, wie der Fokusmodus aller Frame-Source-Komponenten vor dem Session-Zusammenbau geändert wird:

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

Dieser Prozess kann auch im Editor durchgeführt werden, wobei ebenfalls alle Komponenten konfiguriert werden müssen:

Alternativtext

Die Konfiguration für die Frame-Sources ARCoreARFoundationFrameSource und ARKitARFoundationFrameSource befindet sich in der Komponente der Main Camera.

Warnung

Auf diese Weise gefundene AR-Komponenten sind nur für die Konfiguration vor der Laufzeit geeignet.
Da der Zusammenbauprozess AR-Komponenten filtert, sind über die Szenenhierarchie abgerufene AR-Komponenten möglicherweise nicht in der Session enthalten und funktionieren nicht.

Verwendung der zusammengebauten AR-komponenten während der laufzeit

Die in der Session laufenden AR-Komponenten werden erst nach der Montage bestimmt. Vor Abschluss der Montage kann keine AR-Komponente verwendet werden. Auf die montierten AR-Komponenten kann über die Eigenschaft Assembly zugegriffen werden.

Assembly ist verfügbar, wenn der Status der Session ≥ Assembled ist. Genauer gesagt wird die Eigenschaft Assembly erst nach Abschluss der Ausführung der Methode Assemble() zugewiesen, über die auf die Session-Komponenten zugegriffen werden kann. Nachdem die Session beendet oder beschädigt wurde, wird die Eigenschaft Assembly geleert, und die Komponenten sind nicht mehr zugänglich.

In Skripten kann der State der Session überprüft werden, um festzustellen, ob zu diesem Zeitpunkt auf die AR-Komponenten zugegriffen werden kann:

if (Session.State >= ARSession.SessionState.Ready)
{
    // Assembly ist verfügbar
}
else
{
    // Assembly ist nicht verfügbar
}

Alternativ kann das StateChanged-Ereignis abonniert werden, um Statusänderungen der Session zu erhalten und so zum richtigen Zeitpunkt auf die AR-Komponenten zuzugreifen. Um den Status Ready erfassen zu können, muss das StateChanged-Ereignis in der Regel vor dem Start der Session abonniert werden. Dieses Abonnement sicher in der Awake()-Methode durchzuführen, ist üblich:

void Awake()
{
    Session.StateChanged += (state) =>
    {
        if (Session.State == ARSession.SessionState.Ready)
        {
            // Assembly ist verfügbar und bleibt zugänglich, bis die Session beendet oder beschädigt wird
        }
        else if (Session.State < ARSession.SessionState.Ready)
        {
            // Assembly ist nicht verfügbar und bleibt unzugänglich, bis die Session neu gestartet wird
        }
        else
        {
            // Assembly ist verfügbar (normalerweise keine zusätzliche Behandlung erforderlich)
        }
    };
}
Vorsicht

Wenn AR-Komponenten über Methoden wie FindAnyObjectByType<T>() oder GetComponent<T>() abgerufen werden, sind sie definitiv in der Session enthalten und können auch während der Laufzeit verwendet werden.
Es ist sicher, Referenzen auf diese Komponenten zu speichern, aber bei ihrer Verwendung muss sichergestellt werden, dass die Session läuft und diese Komponenten korrekt in der Session enthalten sind, da sonst Ausnahmen oder unerwartetes Verhalten auftreten können.
Vor dem Start und nach dem Stopp der Session funktionieren diese Komponenten nicht. Es wird empfohlen, auch bei dieser Verwendungsweise auf den State und das StateChanged-Ereignis der Session zu achten.

Zugriff auf frame source-komponente

Die ARAssembly.FrameSource-Eigenschaft ermöglicht den Zugriff auf die frame source-komponente. In einer ordnungsgemäß funktionierenden session gibt es genau eine ARAssembly.FrameSource.

Bei der Verwendung der session ist es oft notwendig, den tatsächlich verwendeten frame source-komponententyp zur Laufzeit über ARAssembly.FrameSource zu ermitteln, um auf typspezifische Eigenschaften und Methoden zuzugreifen.

Beispielsweise zeigt der folgende Code, wie je nach frame source unterschiedliche Flächendetektionsmethoden verwendet werden:

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

Zugriff auf frame filter-komponenten

Auf frame filter-komponenten kann über die Eigenschaft ARAssembly.FrameFilters zugegriffen werden. In einer funktionierenden session kann die Liste ARAssembly.FrameFilters mehrere Komponenten desselben Typs enthalten.

Beispielsweise zeigt der folgende Code, wie ein MegaTrackerFrameFilter in der session abgerufen und das entsprechende ereignis registriert wird:

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

Zugriff auf die kamera-komponente

Sie können auf die Kamera-Komponente über die ARAssembly.Camera-Eigenschaft zugreifen. Wenn mehrere Kameras in der Szene vorhanden sind, ist dies eine schnelle Möglichkeit, die für AR verwendete Kamera zu finden.

Beispielsweise zeigt der folgende Code, wie die Kamera in der Session abgerufen wird und ein Raycast auf Objekte in der Szene durchgeführt wird:

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

Zugriff auf die origin-komponente

Die ARAssembly.Origin-Eigenschaft ermöglicht den Zugriff auf die origin-komponente.

Beispielsweise zeigt der folgende Code, wie der origin in einer session abgerufen wird und ein frustum, das die aktuelle Kameraposition und -ausrichtung repräsentiert, in der Szene angezeigt wird:

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 ist wichtig zu beachten, dass zunächst geprüft werden muss, ob ARAssembly.Origin existiert.

Anmerkung

ARAssembly.Origin existiert nur in sessions, bei denen die Bewegungsverfolgungsfunktion aktiviert ist.

Zugriff auf die cameraImageRenderer-komponente

Sie können die CameraImageRenderer-Komponente über die Eigenschaft ARAssembly.CameraImageRenderer zugreifen.

Beispielsweise kann dieser Code das RenderTexture des physischen Kamerabildes abrufen:

RenderTexture renderTexture;

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

Beachten Sie, dass zunächst geprüft werden muss, ob ARAssembly.CameraImageRenderer existiert.

Anmerkung

ARAssembly.CameraImageRenderer ist nur in Sessions gültig, in denen das Rendering von EasyAR durchgeführt wird. In der Regel ist es bei Verwendung von AR Foundation oder Head-Mounted-Displays ungültig, da das Rendering des physischen Kamerabildes dann von AR Foundation oder der Head-Mounted-Display-SDK durchgeführt wird.

Auf FrameRecorder-komponente zugreifen

Auf die FrameRecorder-komponente kann über die eigenschaft ARAssembly.FrameRecorder zugegriffen werden.

Beispielsweise startet dieser code die aufzeichnung. Der speicherort der datei hängt von der konfiguration ab und befindet sich standardmäßig im app-internen speicherverzeichnis:

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

Beachten Sie, dass zunächst geprüft werden muss, ob ARAssembly.FrameRecorder vorhanden ist.

[!HINWEIS] ARAssembly.FrameRecorder kann in einigen fällen, wie bei der verwendung von FramePlayer, nicht verfügbar sein.

Nächste schritte

Verwandte themen