Download

Has anyone launched the Steam VR Overlay in the Oculus Rift using UE4?

I am trying to get the Steam VR overlay to launch inside my Oculus rift using UE4, but I have yet to find a method that is acceptable, has anyone had luck with this? I have spoken to several players that were upset by the missing functionality of their Steam game and would like to address this for them, but so far my hands have been tied.

I have already tried using ‘hmd=steamvr’ on the command line, but it leads to many undesirable results, and on a few test computers it simply doesn’t work at all.

I have even gone so far as to try swapping out the HMDDevice in GEngine at runtime, obviously with even worse results.

So I am hoping that somebody, anybody, has considered this besides just the players of VR games made in UE4, because really that is who we aim to please.

Update 1:

So I managed to use a command line parameter ‘hmd=steamvr’ to sort of push this problem forward. It definitely wasn’t a solution as it did more harm than good on a few fronts. The hands switched sides, the Oculus Touch control scheme unbound, and the button brought up the steam overlay, however the screen occasionally decides not to post to the Oculus Rift.

This seems like an awful lot of work just for one button, right?

Some day in the future when HMD’s start acting like real output peripherals and their controllers start acting like real input peripherals, we can have this mess sorted out and one button wont be such a hassle I hope.

Until then, there are limited workarounds. If you can handle re-mapping the Oculus Touch to handle inputs without the standard bindings (missing a few available buttons), and handle detection of what online subsystem the user has launched from, and handle detection of the Oculus HMD even though it is sort of reading out like a Vive HMD, then the game might function as desired. The two button loss for one gain is totally worth it, as most players in Steam will be pretty unhappy without the Steam overlay.

Hope this helps.

I’ve spent the day looking into this and believe I have it mostly working now. My machine was crashing initially, but that turned out to be caused by the Oculus (or something?) returning a not quite normalized matrix through OpenVR.

Used this code to determine when SteamVR actually means Oculus:


        hardwareCaps.HMDDeviceType = GEngine->HMDDevice->GetHMDDeviceType();

#if PLATFORM_WINDOWS
        if (hardwareCaps.HMDDeviceType == EHMDDeviceType::DT_SteamVR)
        {
            // Steam VR uses Open VR and can support Oculus Rift as well, so let's check a bit further in this case:

            vr::IVRSystem* OpenVR = ISteamVRPlugin::Get().GetVRSystem();

            if (OpenVR)
            {
                char StringBuffer[32];
                vr::ETrackedPropertyError Error;
                vr::TrackedDeviceIndex_t unDeviceIndex = 0;

                OpenVR->GetStringTrackedDeviceProperty(unDeviceIndex, vr::ETrackedDeviceProperty::Prop_TrackingSystemName_String, StringBuffer, 32, &Error);
                if (!_strnicmp(StringBuffer, "oculus", 6))
                {
                    hardwareCaps.HMDDeviceType = EHMDDeviceType::DT_OculusRift;
                }
            }
        }
#endif

Only thing left is to flip the hands back. Not sure if this happens every time though? So glad I found your post though!

I pulled this down from the UE4 Perforce, and successfully applied it to our 4.16 build to fix this issue for us. It fixed the issues of the hands being swapped, so everything seems good! (Dont particularly like that they are doing it in Tick, but it is what they did internally to fix it). It might not work the exact same way with your implementation, but it should get you started!

SteamVRController.cpp


    virtual void Tick( float DeltaTime ) override
    {
#if STEAMVRCONTROLLER_SUPPORTED_PLATFORMS
        vr::IVRSystem* VRSystem = GetVRSystem();

        if (VRSystem != nullptr)
        {
            //RegisterDeviceChanges(VRSystem);
            DetectHandednessSwap(VRSystem);
        }

#endif // STEAMVRCONTROLLER_SUPPORTED_PLATFORMS
    }



 void DetectHandednessSwap(vr::IVRSystem* VRSystem)
    {
        const uint32 LeftDeviceIndex = VRSystem->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
        const uint32 RightDeviceIndex = VRSystem->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand);

        // both hands need to be assigned
        if (LeftDeviceIndex != vr::k_unTrackedDeviceIndexInvalid && RightDeviceIndex != vr::k_unTrackedDeviceIndexInvalid)
        {
            // see if our mappings don't match
            if (ControllerStates[LeftDeviceIndex].Hand != EControllerHand::Left || ControllerStates[RightDeviceIndex].Hand != EControllerHand::Right)
            {
                // explicitly assign the handedness
                ControllerStates[LeftDeviceIndex].Hand = EControllerHand::Left;
                ControllerStates[RightDeviceIndex].Hand = EControllerHand::Right;

                int32 ControllerIndex = DeviceToControllerMap[LeftDeviceIndex];

                UnrealControllerIdAndHandToDeviceIdMap[ControllerIndex](int32)EControllerHand::Left] = LeftDeviceIndex;
                UnrealControllerIdAndHandToDeviceIdMap[ControllerIndex](int32)EControllerHand::Right] = RightDeviceIndex;

                // propagate the change
                SteamVRPlugin->SetUnrealControllerIdAndHandToDeviceIdMap(UnrealControllerIdAndHandToDeviceIdMap);
            }
        }
    }

Excellent, I did the same locally - and also updated the OpenVR to the latest version. It seems that OpenVR may choose the wrong hands if it looks before the Touch controllers are tracking. However, if it checks later, once the tracking is happening, it can identify the correct hands at that point and swap to them using the code above. I was about to write that check myself, but then found Epic already had it in the 4.18 code.

Also, we went ahead and added a new enum for the HMD type, EHMDDeviceType:: DT_SteamVrRift. There were enough places where it needed to be treated one way or the other that this ends up being worth the trouble.