Table of Contents

AR-Funktionskomponenten in der Session aufrufen

In einer laufenden Session konnen Sie uber die Eigenschaft Assembly auf verschiedene Funktionskomponenten zugreifen. In diesem Artikel wird beschrieben, wie Sie auf diese Komponenten zugreifen und was dabei zu beachten ist.

Vor dem Start

AR-Komponenten wahrend der Bearbeitung oder vor dem Start konfigurieren

Manchmal mussen bestimmte Optionen einer Komponente, zum Beispiel DesiredFocusMode, vor dem Start der Komponente gesetzt werden. Wenn Sie Komponenten nicht erst nach dem Start der Session manuell konfigurieren und starten mochten, ist ein einfacher Weg, alle moglichen Frame-Source-Komponenten vor dem Assemble der Session zu konfigurieren. Beim Assemble bleiben eine oder mehrere dieser Komponenten erhalten und ubernehmen ihre Konfiguration.

Sie konnen Standardmethoden von Unity wie FindAnyObjectByType<T>() oder GetComponent<T>() verwenden, um Komponenten zu finden und sie dann zu konfigurieren.

Anmerkung

Ob die auf diese Weise erhaltenen AR-Komponenten zur Laufzeit in die Session aufgenommen werden, ist nicht sicher. Sie mussen daher alle moglichen Falle konfigurieren.

Das folgende Beispiel zeigt, wie vor dem Session-Assemble der Fokusmodus aller Frame-Source-Komponenten geandert 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 Vorgang kann auch im Editor erledigt werden; dann mussen alle Komponenten konfiguriert werden:

alt text

Die Konfigurationen fur Frame-Source-Komponenten der Typen ARCoreARFoundationFrameSource und ARKitARFoundationFrameSource entsprechen den Komponenten auf der Main Camera.

Warnung

Auf diese Weise erhaltene AR-Komponenten konnen nur fur die Konfiguration vor der Laufzeit verwendet werden. Da der Assemble-Prozess AR-Komponenten filtert, konnen die uber die Szenenhierarchie erhaltenen Komponenten moglicherweise nicht in die Session aufgenommen werden und funktionieren dann nicht korrekt.

Wahrend der Laufzeit zusammengesetzte AR-Komponenten verwenden

Die in der Session laufenden AR-Komponenten werden nach dem Assemble bestimmt. Solange das Assemble nicht abgeschlossen ist, kann keine AR-Komponente verwendet werden. Die zusammengesetzten AR-Komponenten konnen uber die Eigenschaft Assembly abgerufen werden.

Assembly ist verfugbar, wenn der Zustand der Session >= Assembled ist. Konkret wird die Eigenschaft Assembly erst nach Abschluss der Methode Assemble() zugewiesen, sodass auf die Session-Komponenten zugegriffen werden kann. Nachdem die Session gestoppt wurde oder ungultig geworden ist, wird die Eigenschaft Assembly wieder geloscht und Komponenten konnen nicht mehr abgerufen werden.

Sie konnen im Skript den Zustand der Session uberprufen, um festzustellen, ob AR-Komponenten zu diesem Zeitpunkt zugreifbar sind:

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

Sie konnen auch das Ereignis StateChanged abonnieren, um Zustandsanderungen der Session zu erhalten und AR-Komponenten zum richtigen Zeitpunkt zu verwenden. Im Allgemeinen sollten Sie das Ereignis vor dem Start der Session abonnieren, wenn Sie den Zustand Ready erfassen mochten. Das Abonnieren in Awake() ist normalerweise sicher:

void Awake()
{
    Session.StateChanged += (state) =>
    {
        if (Session.State == ARSession.SessionState.Ready)
        {
            // Assembly ist verfugbar. Ab diesem Zeitpunkt bleibt Assembly verfugbar, bis die Session gestoppt oder ungultig wird.
        }
        else if (Session.State < ARSession.SessionState.Ready)
        {
            // Assembly ist nicht verfugbar. Ab diesem Zeitpunkt bleibt Assembly bis zum Neustart der Session nicht verfugbar.
        }
        else
        {
            // Assembly ist verfugbar. In der Regel ist hier keine Behandlung notig.
        }
    };
}
Vorsicht

Wenn Sie AR-Komponenten uber Methoden wie FindAnyObjectByType<T>() oder GetComponent<T>() erhalten, sind sie mit Sicherheit in die Session aufgenommen und konnen zur Laufzeit verwendet werden. Es ist sicher, Verweise auf diese Komponenten zu speichern. Wenn Sie sie verwenden, mussen Sie jedoch sicherstellen, dass die Session lauft und diese Komponenten korrekt in die Session aufgenommen wurden. Andernfalls konnen Ausnahmen oder unerwartetes Verhalten auftreten. Diese Komponenten sind vor dem Start der Session und nach dem Stopp nicht funktionsfahig. Auch bei dieser Nutzung wird empfohlen, auf den Zustand der Session State und das Ereignis StateChanged zu achten.

Frame-Source-Komponenten aufrufen

Sie konnen die Frame-Source-Komponente uber die Eigenschaft ARAssembly.FrameSource aufrufen. In einer normal laufenden Session gibt es genau eine ARAssembly.FrameSource.

Bei Verwendung der Session mussen Sie normalerweise auf ARAssembly.FrameSource zugreifen, um den tatsachlichen Typ der zur Laufzeit verwendeten Frame-Source-Komponente zu bestimmen und so ihre speziellen Eigenschaften und Methoden zu nutzen.

Das folgende Beispiel zeigt zum Beispiel, wie je nach Typ der Frame Source unterschiedliche Methoden zur Ebenenerkennung 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;
        }
    }
}

Frame-Filter-Komponenten aufrufen

Sie konnen Frame-Filter-Komponenten uber die Eigenschaft ARAssembly.FrameFilters aufrufen. In einer normal funktionierenden Session konnen sich in der Liste ARAssembly.FrameFilters mehrere Komponenten beliebiger Typen befinden.

Das folgende Beispiel zeigt zum Beispiel, wie ein MegaTrackerFrameFilter aus der Session abgerufen und fur sein entsprechendes Ereignis registriert wird:

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

Die Kamera-Komponente aufrufen

Sie konnen die Kamera-Komponente uber die Eigenschaft ARAssembly.Camera aufrufen. Das ist eine schnelle Moglichkeit, die fur AR verwendete Kamera zu finden, wenn sich mehrere Kameras in der Szene befinden.

Das folgende Beispiel zeigt, wie die Kamera der Session abgerufen und eine Strahlprufung fur Objekte in der Szene durchgefuhrt wird:

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

Origin-Komponente aufrufen

Sie konnen die Origin-Komponente uber die Eigenschaft ARAssembly.Origin aufrufen.

Das folgende Beispiel zeigt, wie die Origin der Session abgerufen und ein Kegel angezeigt wird, der die aktuelle Kameraposition und -ausrichtung in der Szene darstellt:

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

Beachten Sie, dass zuerst gepruft werden muss, ob ARAssembly.Origin vorhanden ist.

Anmerkung

ARAssembly.Origin existiert nur in Sessions, in denen Motion Tracking aktiviert ist.

Die CameraImageRenderer-Komponente aufrufen

Sie konnen die Komponente CameraImageRenderer uber die Eigenschaft ARAssembly.CameraImageRenderer aufrufen.

Das folgende Beispiel zeigt, wie die RenderTexture des physischen Kamerabildes abgerufen wird:

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 zuerst gepruft werden muss, ob ARAssembly.CameraImageRenderer vorhanden ist.

Anmerkung

ARAssembly.CameraImageRenderer ist nur in Sessions gultig, in denen das Rendering von EasyAR ausgefuhrt wird. Im Allgemeinen ist sie bei Verwendung von AR Foundation oder HMDs ungultig, da das Rendering des physischen Kamerabildes dann von AR Foundation oder dem HMD-SDK ubernommen wird.

Die FrameRecorder-Komponente aufrufen

Sie konnen die Komponente FrameRecorder uber die Eigenschaft ARAssembly.FrameRecorder aufrufen.

Das folgende Beispiel zeigt, wie die Aufnahme gestartet wird. Der Speicherort der Datei hangt von der Konfiguration ab und liegt standardmaßig im internen Speicherverzeichnis der Anwendung:

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

Beachten Sie, dass zuerst gepruft werden muss, ob ARAssembly.FrameRecorder vorhanden ist.

Anmerkung

ARAssembly.FrameRecorder ist in seltenen Fallen nicht verfugbar, zum Beispiel wenn FramePlayer verwendet wird.

Nachste Schritte

  • Erfahren Sie, wie Sie Session-Ausgaben abrufen, die die Ausgabedaten der AR-Komponenten enthalt
  • Außerdem konnen Sie den Zugriff auf Komponenten mit diesen Beispielen erkunden:

Verwandte Themen