Überprüfen Sie, ob das OpenVR / SteamVR / OculusVR-Headset auf Ihrem Kopf montiert ist

7

Der Oculus und der Vive verfügen über diesen Lichtnäherungssensor, der erkennt, ob Sie Ihr VR-Headset gerade auf Ihrem Kopf platziert haben oder nicht.

Gibt es eine Möglichkeit, dies für unsere eigenen Spielprüfungen zu nutzen? ZB können wir das Spiel anhalten oder neu starten, je nachdem, ob das Headset getragen wird oder nicht.

Ich verwende Unity / C #, aber jede Hilfe (auf Treiber- / API-Ebene) wird sehr geschätzt.

Spektralsprung
quelle
Der einzige andere Thread im Internet darüber ist dieser, aber keine wirkliche Lösung: forums.oculus.com/developer/discussion/23927/…
Spectraljump

Antworten:

7

Ja, OpenVR hat Ereignisse dafür:

VREvent_TrackedDeviceUserInteractionStarted wird ausgelöst, wenn die Geräte von Standby -> UserInteraction oder Idle -> UserInteraction wechseln. VREvent_TrackedDeviceUserInteractionEnded wird ausgelöst, wenn die Geräte von UserInteraction_Timeout -> Idle wechseln

Darüber hinaus können Sie den Status des Headsets mit pollen GetTrackedDeviceActivityLevelvon Valve.VR.IVRSystem . Welches einen der folgenden Werte zurückgibt:

public enum EDeviceActivityLevel
{
    k_EDeviceActivityLevel_Unknown = -1,
    k_EDeviceActivityLevel_Idle = 0,
    k_EDeviceActivityLevel_UserInteraction = 1,
    k_EDeviceActivityLevel_UserInteraction_Timeout = 2,
    k_EDeviceActivityLevel_Standby = 3,
}

In den Unity-Skripten (Scripts / Core / VRView.cs: GetIsUserPresent () ist auch eine gewisse Ebene davon eingeführt.

MichaelHouse
quelle
Wunderschönen. In der Zwischenzeit habe ich auch das Ereignis Oculus OVRManager.HMDMounted gefunden, falls jemand das benötigt.
Spectraljump
In Unity mit dem OpenVR-Plugin lautet die zu überprüfende Funktion: OpenVR.System.GetTrackedDeviceActivityLevel (0) Ich habe jedoch festgestellt, dass nicht überprüft wird, wann sich das Headset auf dem Kopf einer anderen Person befindet, sondern nur, wann sich das Headset bewegt hat. 10s ohne Bewegung und es geht zurück in den Standby.
Niltoid
Hängt wahrscheinlich vom Gerät ab und davon, wie sie ihre Software für die Arbeit mit OpenVR implementiert haben.
MichaelHouse
Sinnvoll
2

Einschalten, um ein Ereignis mit montiertem / Näherungssensor für das Oculus OVR Unity Plugin zu überprüfen. Dies ist in OVRManager:

/// <summary>
/// Occurs when an HMD is put on the user's head.
/// </summary>
public static event Action HMDMounted;

/// <summary>
/// Occurs when an HMD is taken off the user's head.
/// </summary>
public static event Action HMDUnmounted;

Was in der Quelle vorhanden ist, aber aus irgendeinem Grund nicht durch Durchsuchen der Oculus-Dokumente angezeigt wird .

[BEARBEITEN]

Wenn Sie nicht möchten, dass Oculus das Spiel auf einem schwarzen Bildschirm anhält, wenn Sie das Headset abnehmen:

  • Wenn Sie mit Version 1.3 (2016) oder darunter, des Oculus SDK, dann setzt runInBackground = truein OVRManager, die von der Einheit der eigenen unabhängige runInBackgroundEinstellung.

  • In neueren Versionen verwenden Sie Unity's Application.runInBackground = trueundCamera.stereoTargetEye = StereoTargetEyeMask.None

[EDIT2]

Die OVRManager-Ereignisse haben bei mir überhaupt nicht funktioniert. Was funktioniert, ist die OVRPluginKlasse zu benutzen und sich if (!OVRPlugin.userPresent && m_wasUserPresent)selbst zu tun .

Spektralsprung
quelle
2

In Unity funktioniert Folgendes mit dem OpenVR Unity-Plugin:

print(SteamVR_Controller.Input(0).GetPress(EVRButtonId.k_EButton_ProximitySensor));

Übrigens, in einer Antwort auf die akzeptierte Antwort, die ich vorgeschlagen habe:, OpenVR.System.GetTrackedDeviceActivityLevel(0)aber das ist mehr, um die jüngste Bewegung innerhalb von 10 Sekunden zu erkennen.

Niltoid
quelle
Wow, da ist ein Näherungssensor "Button" definiert. :) Schöne Entdeckung.
Spectraljump
1
Update: Wenn diese OpenVR-Methode (noch) nicht für Oculus funktioniert, scheint es einen Fehler im openvr-Treiber für das Oculus zu geben: steamcommunity.com/app/358720/discussions/0/405691491125141530/…
Spectraljump
2

Sie können jetzt auch UnityEngine.XRund XRDevice.userPresenceohne zusätzliche APIs verwenden: https://docs.unity3d.com/ScriptReference/XR.XRDevice-userPresence.html

Beispielsweise :

if(trackingPresence == true)
    {
        if(XRDevice.userPresence == UserPresenceState.Present && playerPresent == false)
        {
            playerPresent = true;
            Debug.Log("[PLAYER PRESENCE DETECTOR] player is now present");
        }

        if(XRDevice.userPresence == UserPresenceState.NotPresent && playerPresent == true)
        {
            playerPresent = false;
            Debug.Log("[PLAYER PRESENCE DETECTOR] player is now absent");
        }
    }
a_rrats
quelle
Nett. Schließlich. Es wird darauf hingewiesen, dass es sich um eine API auf hoher Ebene handelt und nicht explizit um die Nähe: "Das genaue Verhalten dieser Eigenschaft hängt von jedem Gerätetyp ab. Einige Geräte verfügen über einen Sensor, der speziell die Nähe des Benutzers erkennt, und Benutzer verlassen sich auf Bewegung."
Spectraljump
1

In Android gibt es den Näherungssensor . Dies wird verwendet, um den Bildschirm zu deaktivieren, wenn Sie jemanden anrufen. Ich bin nicht sicher, ob Sie in Unity Zugriff auf den Näherungssensor haben, aber Sie können die native Methode über Unity aufrufen.

Lyinch
quelle
1

Wenn jemand die Oculus VR-Anwendung zwingen möchte, das Spiel nicht anzuhalten, während das Headset ausgeschaltet ist, müssen Sie einige DLL-Aufgaben ausführen. [Quelle]

Hier ist, wie und ich habe auch Code für die SteamVR / OpenVR-Einstellungen eingefügt:

    using System.Runtime.InteropServices;
    [DllImport("OVRPlugin", CallingConvention = CallingConvention.Cdecl)]
    public static extern bool ovrp_SetAppIgnoreVrFocus(bool value);
    [DllImport("OVRPlugin", CallingConvention = CallingConvention.Cdecl)]
    public static extern uint ovrp_GetStatus2(uint query);

    void Start () {
        Application.runInBackground = true; 
        SteamVR_Render.instance.pauseGameWhenDashboardIsVisible = false;
        ovrp_SetAppIgnoreVrFocus(true);
        //ovrp_GetStatus2(uint query);
        //m_vrCam.stereoTargetEye = StereoTargetEyeMask.None;
    }
Spektralsprung
quelle
1

Der SteamVR-Eingang wurde kürzlich vollständig geändert. Er verwendet jetzt Aktionen. Hier finden Sie eine schrittweise Anleitung vom Ventil zur Einrichtung.

Hier ist eine der (besten) Möglichkeiten, um es im Code abzufragen:

    void Update(){


    //NOTE: I could have used one-off events. But I used these constant Update() polls instead because if the VR Dashboard is on while the headset is taken off or put on, 
    //then the OnDown and OnUp events get eaten by the dashboard and will never reach this code in unity. (github issue here: https://github.com/ValveSoftware/openvr/issues/628)

    // m_inputSourceDevice needs to be Any - there's no entry for "Headset", but the headset's sensors are reported under the Any "hand".
    SteamVR_Input_Sources m_inputSourceDevice = SteamVR_Input_Sources.Any;

    if(!m_isHeadsetOn && SteamVR_Input._default.inActions.Proximity_Sensor.GetState(m_inputSourceDevice)){
            Debug.Log("Headset On.");
            HeadsetOn();
    }
    else if(m_isHeadsetOn && !SteamVR_Input._default.inActions.Proximity_Sensor.GetState(m_inputSourceDevice)){
        Debug.Log("Headset Off (cancellable)");
        StartCoroutine(HeadsetOff());
    }

}

Beachten Sie, dass es ab sofort einen Fehler gibt, der Sie daran hindert, SteamVR zu verwenden, um den Näherungssensor einer Aktion zuzuweisen, wenn Sie ein HTC Vive oder Vive Pro haben, obwohl es ironischerweise wie beabsichtigt funktioniert, wenn Sie es mit einem verwenden Oculus Headset. Auf dieser Seite mit Steamvr-Github-Problemen gibt es eine einfache Lösung .

Beachten Sie auch, dass OpenVR in der Regel das implementiert, was SteamVR bietet. Derzeit können Sie jedoch nicht auf den Näherungssensor zugreifen. Das einzige, was Sie mit OpenVR tun können, ist das zu überprüfen, EDeviceActivityLevelwie MichaelHouse in seiner Antwort erklärt hat. Dies ist jedoch nutzlos, da die einzige Ebene, an der der Prox-Sensor beteiligt ist, die k_EDeviceActivityLevel_UserInteractionVerbindung zwischen Prox und Kreisel ist. Laut OpenVR interagiert das Headset also für immer mit dem Benutzer, solange eine leichte Brise oder Vibration den Neigungssensor kippt Headset alle 10 Sekunden ein wenig.

[BEARBEITEN]

Einige Dinge wurden in der Zwischenzeit behoben. Zum Beispiel gibt es jetzt einen Eintrag für den Hmd anstelle von Any; und OpenVR hat einen XRDevice.userPresence-Wert (obwohl dies möglicherweise nicht explizit der Näherungssensor ist).

Spektralsprung
quelle
Vielen Dank, dass Sie eine neue Antwort mit den neuesten Informationen erstellt haben!
MichaelHouse
0

Für OVR ovr_GetSessionStatus()sagt Ihnen dies, OVRSessionStatushat ein Feld HmdMounted.

Alex
quelle