Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Cross-platform VR development: GearVR and Daydream

Discussion in 'AR/VR (XR) Discussion' started by jmitcheson, Feb 7, 2017.

  1. jmitcheson

    jmitcheson

    Joined:
    Oct 21, 2016
    Posts:
    95
    Hi all,

    I've created a couple of projects for the GearVR. I'm looking to start a new project and I want to support both GearVR and Daydream. Before I start, I wanted to see if anyone had any tips, articles etc. on how to manage this.

    What confuses me most is the UI systems. Oculus has a reference implementation for a gaze cursor and a custom InputModule. Unity's VR samples provide the cross-platform "VRInteractiveItem" and associated classes, but it doesn't seem to work as smoothly with the input system (there is no InputModule and events all have to be hooked up manually). The GoogleVR SDK for Unity has it's own code and prefabs for gaze cursors. In addition, Daydream has a separate controller and in the GoogleVR samples, the pointing is done with the controller rather than the user's gaze so there is a bit of a conceptual difference there.

    So, should I
    • Use Unity's VR sample code
    • Maintain two platform specific implementations, and have a switch at runtime depending on the platform?
    • Have a project for each platform?!
    Basically any tips or stories you have about supporting and releasing to both of these platforms for the same project would be greatly appreciated!

    Thanks
     
  2. Selzier

    Selzier

    Joined:
    Sep 23, 2014
    Posts:
    579
    Use a Gaze Input Module- either your own, or the one from GoogleVR, etc. They are just scripts, so you can use the same ones for Cardboard, Daydream , GearVR, etc. Google VR's is works nice:


    If you have 'VR Supported' in build settings (daydream and gearvr), then you need to get center of screen slightly different than the default Gaze Input Module:


    I have a Mobile VR Interaction Pack coming out soon to solve this problem:
     
  3. jmitcheson

    jmitcheson

    Joined:
    Oct 21, 2016
    Posts:
    95
    Thanks for the reply. So if I used, say the Oculus GazeInputModule and then imported the Daydream SDK (or used the technical preview) then basic gaze pointing would work just fine on the Daydream?

    My main problem is I don't have a Daydream phone to test with right now, and I don't want to find out later on down the track that I didn't get my UI system right!
     
  4. elpinguinofrio

    elpinguinofrio

    Joined:
    Aug 9, 2017
    Posts:
    3
    another problem I've seen is a camera: I'm very new here so I might miss something essential, but when I compile standard Google project https://github.com/googlevr/gvr-unity-sdk/releases, it looks different on the exact same phone Samsung Galaxy s8: there's "eye fish" effect on the Gear VR. So I assume camera has to acquire headset specks during run time and it's different for Gear VR and daydream headsets.
     
  5. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    I'm working on GearVR/Daydream compatibility in my current project right now.

    My goal is to have one project, that I can build for each target with minimal effort to set the build mode. I refuse to fork.

    I want to just do this:
    1. Set one VR platform in Unity VR list. (GearVR, Daydream or None)
    2. Build.
    3. Done.
    Here's some points I've discovered so far.

    EDIT: best to just jump to this future post: Cross-platform VR development: GearVR and Daydream

    Daydream: you can have a regular camera in scene and daydream "hooks" into that when Daydream is added to VR list. Just add GVREditorEmulator and GVRControllerInput to some scene object and you're done, you can proceed to call all GVR static functions.

    GearVR: you must place OVRCameraRig prefab into scene, there can be no regular cam in scene. I have yet to work out if this can be swapped out dynamically, I think not, I think OVRCameraRig has to be there at engine init?

    Small fly in the ointment: When building daydream target: you should remove (maybe rename) the Assets/OVR/Plugins folder if you have one, if you fail to do this then the daydream game will cause any samsung phone with GearVR service running to popup "place phone in GearVR", even if "GearVR" is not in unity VR list (and thus not referenced in manifest). Many samsung users are getting this issue when trying to play daydream games right now, their workaround is to disable oculus services, but that's hardly conducive to a nice end user experience.

    You can leave your Assets/Plugins/Android/assets/oculussig_xxxxx file where it is for daydream builds.

    For daydream samsung S8/S8+ (and maybe other targets?) single pass rendering yields black at the moment, I set to multi pass for now.

    I am using ETC2 texture compression for now, ASTC for final production build.

    CAMERA:


    I'm doing runtime VR mode detection once upon game startup like this, I wait for v.bInitialised to go true until the game then proceeds to load/build further scenery:
    Code (CSharp):
    1.  
    2.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    3.         //    INIT CAMERA FOR VR SYSTEM TYPE
    4.         private void InitSystemType()
    5.         {
    6.             //  WAIT FOR MAIN CAM TO COME UP
    7.             v.oCameraActive = Camera.main;
    8.             if (!v.oCameraActive)
    9.             {
    10.                 Invoke("InitSystemType", 0.1f);
    11.                 LOGW("NO Camera.main");
    12.                 return;
    13.             }
    14.             main.g.cLibMesh.ChildObjectToParent(v.oCameraActive.gameObject, this.gameObject);
    15.             LOGM("FOUND Camera.main");
    16.  
    17.             //  WHAT CAM PREFAB
    18.             string sCameraPrefab = "";
    19.  
    20.             //  GET VR SYSTEM NAMES INTO A LIST
    21.             string[] asDevices = VRSettings.supportedDevices;
    22.             List<string> lsDevices = new List<string>();
    23.             for (int iDevice = 0; iDevice < asDevices.Length; iDevice++)
    24.             {
    25.                 lsDevices.Add(asDevices[iDevice].ToUpper());
    26.             }
    27.  
    28.             //    GEARVR
    29.             if (lsDevices.Contains(K_S_VR_DEVICE_LIST_NAME_GEARVR))
    30.             {
    31.                 v.eSystemType = E_SYSTEM_TYPE.GEARVR;
    32.                 sCameraPrefab = "vr_camera_gearvr";//OVRCameraRig and OVRManager in this prefab. And 2 OVRGearVRControllers are in the OVRCameraRig heirachy.
    33.  
    34.                 if (v.oCameraActive)
    35.                 {
    36.                     DestroyImmediate(v.oCameraActive.gameObject);
    37.                 }
    38. #if(UNITY_EDITOR)
    39.                 v.bSynthesizeHMDRotation = true;
    40. #else
    41.                 v.bSynthesizeHMDRotation = false;
    42. #endif
    43.             }
    44.  
    45.             //    DAYDREAM
    46.             else if (lsDevices.Contains(K_S_VR_DEVICE_LIST_NAME_DAYDREAM))
    47.             {
    48.                 v.eSystemType = E_SYSTEM_TYPE.DAYDREAM;
    49.                 sCameraPrefab = "vr_camera_daydream";//GVREditorEmulator and GVRControllerInput in this prefab.
    50.             }
    51.  
    52.             //    NONE
    53.             else
    54.             {
    55.                 sCameraPrefab = "vr_camera_none";//just a dummy transform in this prefab.
    56.                 v.eSystemType = E_SYSTEM_TYPE.NONE;
    57.                 v.bSynthesizeHMDRotation = true;
    58.             }
    59.  
    60.             //  LOAD RELEVANT PREFAB
    61.             GameObject oCameraPrefab = main.g.cLibMesh.CreateObject("VR/Prefabs/" + sCameraPrefab);
    62.             if (!oCameraPrefab)
    63.             {
    64.                 LOGE("CANT LOAD CAMERA PREFAB " + sCameraPrefab);
    65.                 return;
    66.             }
    67.  
    68.             v.tCameraPrefab = oCameraPrefab.transform;
    69.             main.g.cLibMesh.ChildObjectToParent(v.tCameraPrefab, this.transform);
    70.             v.tCameraPrefab.name = sCameraPrefab.ToUpper();
    71.  
    72.             //  SET CAM
    73.             v.oCameraActive = Camera.main;
    74.             main.g.cLibMesh.ChildObjectToParent(v.oCameraActive.gameObject, this.gameObject);
    75.             v.oCameraActive.nearClipPlane = K_F_CAMERA_PLANE_NEAR;
    76.             v.oCameraActive.farClipPlane = K_F_CAMERA_PLANE_FAR;
    77.             v.oCameraActive.backgroundColor = Color.black;
    78.  
    79.             //  DONE
    80.             v.bInitilised = true;
    81.             LOGM("SYSTEM TYPE SET TO: " + v.eSystemType);
    82.         }
    83.  
    84.  
    My only issue is getting GearVR to init properly at runtime, I get 2 log warnings per frame:
    ovrp_GetAppHasInputFocus return Failure_NotInitialized
    ovrp_GetAppHasSystemOverlayPresent return Failure_NotInitialized


    Searching google for either of these warnings gives zero results, so I'm obviously way out in the weeds here.

    I'm not able to find docs on how to programattically instantiate Oculus in unity script, maybe the prefabs have to be in scene at start?

    INPUT:


    For input I am including both APIs and switching when polling like this. Then the relevant control state is stored in a superset abstraction class I made.

    Code (CSharp):
    1.  
    2.         public class C_BUTTON
    3.         {
    4.             public bool bDown;
    5.             public bool bJustUp;
    6.             public bool bJustDown;
    7.             //  UPDATE
    8.             public void Update(bool bDownNow)
    9.             {
    10.                 bJustDown = (bDownNow && !bDown);
    11.                 bJustUp = (!bDownNow && bDown);
    12.                 bDown = bDownNow;
    13.             }
    14.         }
    15.  
    16.         public class C_BUTTONS
    17.         {
    18.             public bool bFresh;
    19.             public C_BUTTON cBtn_App = new C_BUTTON();
    20.             public C_BUTTON cBtn_PadClick = new C_BUTTON();
    21.             public C_BUTTON cBtn_PadTouch = new C_BUTTON();
    22.             public C_BUTTON cBtn_Trigger = new C_BUTTON();
    23.         }
    24.  
    25.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    26.         //    LATE UPDATE
    27.         private void LateUpdate()
    28.         {
    29.             if (!v.bActive)
    30.             {
    31.                 return;
    32.             }
    33.  
    34.             //  DATA NOT FRESH FOR NEXT FRAME
    35.             v.cButtons.bFresh = false;
    36.             v.cTouchPad.bFresh = false;
    37.             v.bBatterState_Fresh = false;
    38.             v.bControllerRotation_Fresh = false;
    39.         }
    40. ....
    41. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    42.         //    GET STATE OF ALL BUTTONS
    43.         public C_BUTTONS Controller_GetButtons()
    44.         {
    45.             //  NEED TO GET FRESH DATA?
    46.             if (!v.cButtons.bFresh)
    47.             {
    48.                 //---------------------------------------------------------------------------------------------------------------------
    49.                 //    DAY DREAM
    50.                 if (v.eSystemType == E_SYSTEM_TYPE.DAYDREAM)
    51.                 {
    52.                     v.cButtons.cBtn_App.Update(GvrControllerInput.AppButton);
    53.                     v.cButtons.cBtn_PadClick.Update(GvrControllerInput.ClickButton);
    54.                     v.cButtons.cBtn_PadTouch.Update(GvrControllerInput.IsTouching);
    55.                     //v.cButtons.cBtn_Trigger.Update(false); NO TRIGGER ON DAYDREAM
    56.                 }
    57.                 //---------------------------------------------------------------------------------------------------------------------
    58.                 //    GEAR VR
    59.                 else if (v.eSystemType == E_SYSTEM_TYPE.GEARVR)
    60.                 {
    61.                     v.cButtons.cBtn_App.Update(OVRInput.Get(OVRInput.Button.Back));
    62.                     v.cButtons.cBtn_PadClick.Update(OVRInput.Get(OVRInput.Button.PrimaryTouchpad));
    63.                     v.cButtons.cBtn_PadTouch.Update(OVRInput.Get(OVRInput.Touch.PrimaryTouchpad));
    64.                     v.cButtons.cBtn_Trigger.Update(OVRInput.Get(OVRInput.Button.PrimaryIndexTrigger));
    65.                 }
    66.                 //---------------------------------------------------------------------------------------------------------------------
    67.                 //    NONE
    68.                 else if (v.eSystemType == E_SYSTEM_TYPE.NONE)
    69.                 {
    70.                     v.cButtons.cBtn_App.Update(Input.GetKey(KeyCode.X));
    71.                     v.cButtons.cBtn_PadClick.Update(Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0));
    72.                     v.cButtons.cBtn_PadTouch.Update(v.cNone.vTouchpadPos_Raw.magnitude > 0.0f);
    73.                     v.cButtons.cBtn_Trigger.Update(Input.GetKey(KeyCode.RightAlt));
    74.                 }
    75.  
    76.                 //  NOW FRESH
    77.                 v.cButtons.bFresh = true;
    78.             }
    79.  
    80.             //  DONE
    81.             return v.cButtons;
    82.         }....
    Above is basically what unity will have to do if it wants to "unite" all VR APIs.

    Unity will have to employ some even more general abstraction under the hood, because it will have to handle extra buttons/pads/sticks/orientations found on any potential future input devices. It should allow the unity user to query any systems control state through the same UnityEngine.VR API. A wide problem for sure.
     
    Last edited: Oct 11, 2017
  6. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    Your daydream build must not include any oculus plugins or phones oculus service will wake up. So to build daydream (that will work on a gearVR equipped phone): just have daydream in VR list and remove (temporarily move outside project scope) Assets/OVR/Plugins folder from your project.

    See updated post below for 2017.1.2f1
     
    Last edited: Oct 11, 2017
  7. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    RE pure script useage of these VR APIs
    i.e. choosing and using relevant API at runtime game start:
    More stuff I've discovered using Unity 2017.1.0p4:

    Best to use the built in GearVR plugin, do not import Assets/OVR/Plugins.
    Just import these from Oculus package:
    Assets/OVR/Editor
    Assets/OVR/Prefabs
    Assets/OVR/Scripts

    This way Unity does not include any Oculus plugins if Oculus is not in the VR list.

    For hybrid project:
    always start scene[0] with just one vanilla unity cam.

    Then duing your init phase: swap out for any VR_SDK specific cam with any required VR_SDK scripts on it.

    When game starts, if you find Daydream in unity VR list: DestroyImmediate your oculus_prefab and instantiate new gearvr_prefab: with Camera, GVREditorEmulator and GVRControllerInput on it.

    Best to have a seperate object that holds your audio listener, instantiate it at (0,0,0) on game start and child it to your VR camera once you've got it up and running.

    Build with only one VR platform in unity list: Oculus *or* daydream. Unity will moan with log error that "android VR builds require cardboard or daydream in the list", but it will continue and build fine with just Oculus in the list (as it should).

    Result:
    I can now build daydream or GearVR simply by selecting relevant platform in Unity VR list and hitting "Build", no other steps needed, no #if directives needed.

    Both work correctly on a GalaxyS8 with Oculus service running, i.e. daydream works fine without activating GearVR service.

    If we want newer Oculus plugin version: I think best to wait until it is bundled with a stable unity release.


    Note:

    If any other mobile VR SDK comes out that's as finnicky and particular as Oculus then it will be a problem, thank goodness daydream is more forgiving.

    See updated post below for 2017.1.2f1
     
    Last edited: Oct 11, 2017
  8. adriansotov

    adriansotov

    Joined:
    Jul 14, 2015
    Posts:
    8

    Same here, did you find anything about this warning?
     
  9. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    Not much info about warning, to get around it: follow my below post.
     
    Last edited: Oct 11, 2017
  10. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    GearVR/Daydream one project, easy build switch:

    Unity 2017.1.2f1

    Import latest VR SDK asset packages:
    GoogleVRForUnity_1-7.unitypackage
    ovr_unity_utilities_1.18.1

    I chose to use the plugins bundled with unity, that is: I only imported the required .cs declaration scripts for each SDK, you may want to try the latest plugins included with the relevant github download. However if you do: be sure to remove them from project scope when you build, otherwise they will find their way into your APK and interfere with each other.

    Note: I did have to include the google audio plugin for X86 (to get GVRAudio working in editor), this daydream related plugin can stay in project scope when building for GearVR.

    To easily target build platform: Put one entry into your Unity PlayerSettings VR list, the entry you select will determine your build target.

    Make your game scene[0] have a straight vanilla unity camera in it.

    During game init: ascertain which VR SDK you are running by enumerating VRSettings.supportedDevices.

    Then swap out the vanilla camera for a camera set up for the relevant VR platform (with the required VR_SDK scripts on it for input etc). Can swap by calling DestroyImmediate on vanilla cam and then loading relevant cam prefab.

    NOTES: If using single pass rendering, have at least 2xMSAA enabled and set your cameras "Clear Flags" to "Solid Color".

    All other build/quality settings can be the same for both platforms.

    For production build: Obey the Oculus lint tool, and apply those settings to the project for both GearVR and Daydream: ASTC, IL2CPP etc.
     
    Last edited: Oct 11, 2017
    Arkade likes this.
  11. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    GearVR/Daydream one project, NOTE!

    I just discovered this after hours of poking around:

    Make sure you have different package identifier names for GearVR and DayDream builds.

    If you don't then your phone remembers the package name is associated with daydream, and then if you install the same APK built for oculus: you get wrong final render texture width, this happens even if you uninstall daydream version first. (EDIT uninstalling and restarting phone will cure it).

    Set it in:
    File / BuildSettings / PlayerSettings / AndroidTab / OtherSettings / Identification / PackageName

    Of course we will be having different package names (for Oculus and GooglePlay stores) when finally publishing, but if you forget to change it during development testing, just once, then your target phone will never render the game correctly in gearvr again.
     
    Last edited: Nov 1, 2017
    Arkade, WendelinReich and jmitcheson like this.
  12. jmitcheson

    jmitcheson

    Joined:
    Oct 21, 2016
    Posts:
    95
    Thanks for sharing. Are you using the GearVR controller? Any tips for supporting both controllers easily? I have to port soon and I'm not sure what approach to take.

    One idea I had was to write one single InputModule which would switch in the relevant Google/Oculus input module, and a simple wrapper class to do something similar in the case where the controller values might need to be accessed directly (get last raycast result, etc).
     
    SiliconDroid likes this.
  13. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    @jmitcheson, yes i'm using both daydream/gearvr controllers.

    I'm running a custom rig, swap out controller 3d models on init:

    So I don't use any prefab controller helpers etc. I only need to get low level hardware info:
    • Left/Right handed user.
    • Controller rotation.
    • Touchpad state.
    • Button states.
    • Battery state.
    I did as you allude to and wrote a general VR input class, it calls the static methods of the relevant API.

    I dont need to #ifdef anything out, you can have all OVR/GVR scripts in your project together.

    If you are using the supplied prefabs for controllers, laser pointer with raycast etc. then you should be able to handle that as well; just spawn the prefab you need during init.
     
    Last edited: Oct 21, 2017
    jmitcheson likes this.
  14. jmitcheson

    jmitcheson

    Joined:
    Oct 21, 2016
    Posts:
    95
    @SiliconDroid Thanks for the info. Nice use of the arm model and controller. Your game looks great.

    Slightly OT but do many / most mobile VR games fully embody the player like this? Mine is disembodied at the moment.
     
    SiliconDroid likes this.
  15. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    @jmitcheson I think most mobile VR games are not implementing full body avatars. I guess it's a lot of extra work and also mobile triangle budget is tight.

    I do like having a body and I think it helps ground users and reduce sim sickness. In GearVR (with wider FOV), when I'm settled and only moving my neck muscles and controller hand: I still manage to get that magical feeling of presence (as strong as 6DOF tracking), I can't get it without a body avatar, but maybe that's just me?

    My avatar only has bones in the arms and to help with the triangle budget I performed a laborious hand culling of all unseen triangles from my avatar and cockpit model; similar to what googles new Seurat tool will do automatically.

     
    Last edited: Oct 23, 2017
  16. vivalavida

    vivalavida

    Joined:
    Feb 26, 2014
    Posts:
    83
    HI @SiliconDroid ,

    I've been trying to make a cross-platform build,
    Wanted to know how you manage the AndroidManifest.xml?
    Do you manually change the parameters before build, or is there an Automated way to handle this.

    If possible have AndoridManifest.xml for each platform.

    We've already uploaded a test build to Daydream(Play store) and ran into issues while uploading to GearVR(Oculus) store.
    (worried that if we manually make changes necessary for Oculus It might cause errors while updating the Daydream version in the future.)

    Thanks a lot.
     
  17. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    @vivalavida I've not tried publishing to daydream or gearvr yet, but I will be and will need to understand this (as do you).

    So we can see what manifest is getting bundled like this:
    For checking what's in an actual APK: I like ClassyShark because its a fast small standalone .jar and formats the XML to be very readable.

    So here are my currently generated APKS:

    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.1" package="com.silicondroid.cmwo" android:installLocation="auto">
    3.   <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" />
    4.   <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:theme="@style/UnityThemeSelector" android:debuggable="false" android:isGame="true" android:banner="@drawable/app_banner">
    5.     <activity android:label="@string/app_name" android:name="com.unity3d.player.UnityPlayerActivity" android:screenOrientation="landscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density">
    6.       <intent-filter>
    7.         <action android:name="android.intent.action.MAIN" />
    8.         <category android:name="android.intent.category.LAUNCHER" />
    9.         <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
    10.       </intent-filter>
    11.       <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    12.     </activity>
    13.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:name="com.unity.purchasing.googleplay.PurchaseActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
    14.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:name="com.unity.purchasing.googleplay.VRPurchaseActivity" android:theme="@style/VrActivityTheme">
    15.       <intent-filter>
    16.         <action android:name="com.google.vr.vrcore.ACTION_NONE" />
    17.         <category android:name="com.google.intent.category.DAYDREAM" />
    18.       </intent-filter>
    19.     </activity>
    20.     <!-- For enableVrMode use the value vs. the string so Unity can build it. -->
    21.     <activity android:configChanges="orientation|screenSize" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:exported="false" android:label="@string/app_name" android:name="com.google.gvr.keyboardsupport.TransitionVRActivity" android:resizeableActivity="false">
    22.       <intent-filter>
    23.         <category android:name="android.intent.category.LAUNCHER" />
    24.         <category android:name="com.google.intent.category.DAYDREAM" />
    25.       </intent-filter>
    26.     </activity>
    27.     <!-- For enableVrMode use the value vs. the string so Unity can build it. -->
    28.     <activity android:configChanges="orientation|screenSize" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:exported="false" android:label="@string/app_name" android:name="com.google.gvr.permissionsupport.TransitionVRActivity" android:theme="@android:style/Theme.Dialog">
    29.       <intent-filter>
    30.         <category android:name="android.intent.category.LAUNCHER" />
    31.         <category android:name="com.google.intent.category.DAYDREAM" />
    32.       </intent-filter>
    33.     </activity>
    34.     <meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only" />
    35.     <meta-data android:name="unity.build-id" android:value="40e3d1a4-b5e7-478e-803c-669266dc5147" />
    36.     <meta-data android:name="unity.splash-mode" android:value="0" />
    37.     <meta-data android:name="unity.splash-enable" android:value="False" />
    38.     <meta-data android:name="android.max_aspect" android:value="2.1" />
    39.   </application>
    40.   <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="25" />
    41.   <uses-permission android:name="android.permission.INTERNET" />
    42.   <uses-permission android:name="com.android.vending.BILLING" />
    43.   <!-- Indicates use of Android's VR-mode, available only on Android N+ -->
    44.  <uses-feature android:name="android.software.vr.mode" android:required="false" />
    45.  <!-- Indicates use of VR features that are available only on official "VR-ready" devices -->
    46.  <uses-feature android:name="android.software.vr.high_performance" android:required="false" />
    47.  <uses-permission android:name="android.permission.WAKE_LOCK" />
    48.  <uses-feature android:glEsVersion="0x00020000" />
    49.  <uses-feature android:name="android.hardware.vulkan" android:required="false" />
    50.  <uses-feature android:name="android.hardware.gamepad" android:required="false" />
    51.  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    52.  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
    53.  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
    54. </manifest>
    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.1" package="com.silicondroid.cmwo" android:installLocation="auto">
    3.   <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" />
    4.   <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false" android:isGame="true" android:banner="@drawable/app_banner" android:theme="@style/VrActivityTheme">
    5.     <activity android:label="@string/app_name" android:name="com.unity3d.player.UnityPlayerActivity" android:screenOrientation="landscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:enableVrMode="@string/gvr_vr_mode_component" android:resizeableActivity="false">
    6.       <intent-filter>
    7.         <action android:name="android.intent.action.MAIN" />
    8.         <category android:name="android.intent.category.LAUNCHER" />
    9.         <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
    10.         <category android:name="com.google.intent.category.DAYDREAM" />
    11.       </intent-filter>
    12.       <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    13.       <meta-data android:name="com.google.android.vr.icon" android:resource="@drawable/vr_icon_front" />
    14.       <meta-data android:name="com.google.android.vr.icon_background" android:resource="@drawable/vr_icon_back" />
    15.     </activity>
    16.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:name="com.unity.purchasing.googleplay.PurchaseActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
    17.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:name="com.unity.purchasing.googleplay.VRPurchaseActivity" android:theme="@style/VrActivityTheme">
    18.       <intent-filter>
    19.         <action android:name="com.google.vr.vrcore.ACTION_NONE" />
    20.         <category android:name="com.google.intent.category.DAYDREAM" />
    21.       </intent-filter>
    22.     </activity>
    23.     <!-- For enableVrMode use the value vs. the string so Unity can build it. -->
    24.     <activity android:configChanges="orientation|screenSize" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:exported="false" android:label="@string/app_name" android:name="com.google.gvr.keyboardsupport.TransitionVRActivity" android:resizeableActivity="false">
    25.       <intent-filter>
    26.         <category android:name="android.intent.category.LAUNCHER" />
    27.         <category android:name="com.google.intent.category.DAYDREAM" />
    28.       </intent-filter>
    29.     </activity>
    30.     <!-- For enableVrMode use the value vs. the string so Unity can build it. -->
    31.     <activity android:configChanges="orientation|screenSize" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:exported="false" android:label="@string/app_name" android:name="com.google.gvr.permissionsupport.TransitionVRActivity" android:theme="@android:style/Theme.Dialog">
    32.       <intent-filter>
    33.         <category android:name="android.intent.category.LAUNCHER" />
    34.         <category android:name="com.google.intent.category.DAYDREAM" />
    35.       </intent-filter>
    36.     </activity>
    37.     <meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
    38.     <meta-data android:name="unity.build-id" android:value="727e1c15-b3d0-4dd1-ab43-d088edc91e26" />
    39.     <meta-data android:name="unity.splash-mode" android:value="0" />
    40.     <meta-data android:name="unity.splash-enable" android:value="False" />
    41.     <meta-data android:name="android.max_aspect" android:value="2.1" />
    42.   </application>
    43.   <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="25" />
    44.   <uses-permission android:name="android.permission.INTERNET" />
    45.   <uses-permission android:name="com.android.vending.BILLING" />
    46.   <!-- Indicates use of Android's VR-mode, available only on Android N+ -->
    47.  <uses-feature android:name="android.software.vr.mode" android:required="false" />
    48.  <!-- Indicates use of VR features that are available only on official "VR-ready" devices -->
    49.  <uses-feature android:name="android.software.vr.high_performance" android:required="false" />
    50.  <uses-feature android:glEsVersion="0x00020000" />
    51.  <uses-feature android:name="android.hardware.vulkan" android:required="false" />
    52.  <uses-feature android:name="android.hardware.gamepad" android:required="false" />
    53.  <uses-feature android:name="android.hardware.vr.high_performance" />
    54.  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    55.  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
    56.  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
    57. </manifest>

    My oculus manifest has lots of daydream pollution in it, but currently I have imported the GoogleVR unity package and have it's newer plugins in my project path, that may be causing this pollution (will investigate).

    My daydream manifest seems OK.

    It's possible to over ride the unity generated manifest and supply our own, which could be a hand edited version of the auto generated one, so whatever happens, it's possible to get correct manifests. But that's really painful when it comes to future app updates, it's better if unity just does the correct manifest. Simply select Oculus or Daydream in the XR list and build, that's what we need.

    EDIT: I built an oculus APK after removing the GoogleVR package imported plugins. I still have the unity included GoogleVR plugins, those supplied with unity under the hood.

    Daydream pollution in Oculus manifest is reduced:
    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.1" package="com.silicondroid.cmwo" android:installLocation="auto">
    3.   <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" />
    4.   <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:theme="@style/UnityThemeSelector" android:debuggable="false" android:isGame="true" android:banner="@drawable/app_banner">
    5.     <activity android:label="@string/app_name" android:name="com.unity3d.player.UnityPlayerActivity" android:screenOrientation="landscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density">
    6.       <intent-filter>
    7.         <action android:name="android.intent.action.MAIN" />
    8.         <category android:name="android.intent.category.LAUNCHER" />
    9.         <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
    10.       </intent-filter>
    11.       <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    12.     </activity>
    13.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:name="com.unity.purchasing.googleplay.PurchaseActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
    14.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:name="com.unity.purchasing.googleplay.VRPurchaseActivity" android:theme="@style/VrActivityTheme">
    15.       <intent-filter>
    16.         <action android:name="com.google.vr.vrcore.ACTION_NONE" />
    17.         <category android:name="com.google.intent.category.DAYDREAM" />
    18.       </intent-filter>
    19.     </activity>
    20.     <meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only" />
    21.     <meta-data android:name="unity.build-id" android:value="2bd03ba5-55d8-479a-8ff8-544af6f07f41" />
    22.     <meta-data android:name="unity.splash-mode" android:value="0" />
    23.     <meta-data android:name="unity.splash-enable" android:value="False" />
    24.     <meta-data android:name="android.max_aspect" android:value="2.1" />
    25.   </application>
    26.   <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="25" />
    27.   <uses-permission android:name="android.permission.INTERNET" />
    28.   <uses-permission android:name="com.android.vending.BILLING" />
    29.   <!-- Indicates use of Android's VR-mode, available only on Android N+ -->
    30.  <uses-feature android:name="android.software.vr.mode" android:required="false" />
    31.  <!-- Indicates use of VR features that are available only on official "VR-ready" devices -->
    32.  <uses-feature android:name="android.software.vr.high_performance" android:required="false" />
    33.  <uses-permission android:name="android.permission.WAKE_LOCK" />
    34.  <uses-feature android:glEsVersion="0x00020000" />
    35.  <uses-feature android:name="android.hardware.vulkan" android:required="false" />
    36.  <uses-feature android:name="android.hardware.gamepad" android:required="false" />
    37.  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    38.  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
    39.  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
    40. </manifest>

    Daydream manifest smaller, less redundancy:
    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.1" package="com.silicondroid.cmwo" android:installLocation="auto">
    3.   <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" />
    4.   <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false" android:isGame="true" android:banner="@drawable/app_banner" android:theme="@style/VrActivityTheme">
    5.     <activity android:label="@string/app_name" android:name="com.unity3d.player.UnityPlayerActivity" android:screenOrientation="landscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:enableVrMode="@string/gvr_vr_mode_component" android:resizeableActivity="false">
    6.       <intent-filter>
    7.         <action android:name="android.intent.action.MAIN" />
    8.         <category android:name="android.intent.category.LAUNCHER" />
    9.         <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
    10.         <category android:name="com.google.intent.category.DAYDREAM" />
    11.       </intent-filter>
    12.       <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    13.       <meta-data android:name="com.google.android.vr.icon" android:resource="@drawable/vr_icon_front" />
    14.       <meta-data android:name="com.google.android.vr.icon_background" android:resource="@drawable/vr_icon_back" />
    15.     </activity>
    16.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:name="com.unity.purchasing.googleplay.PurchaseActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
    17.     <activity android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:enableVrMode="com.google.vr.vrcore/com.google.vr.vrcore.common.VrCoreListenerService" android:name="com.unity.purchasing.googleplay.VRPurchaseActivity" android:theme="@style/VrActivityTheme">
    18.       <intent-filter>
    19.         <action android:name="com.google.vr.vrcore.ACTION_NONE" />
    20.         <category android:name="com.google.intent.category.DAYDREAM" />
    21.       </intent-filter>
    22.     </activity>
    23.     <meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
    24.     <meta-data android:name="unity.build-id" android:value="f4e3550d-122c-46c4-a1e5-96f52d051a7d" />
    25.     <meta-data android:name="unity.splash-mode" android:value="0" />
    26.     <meta-data android:name="unity.splash-enable" android:value="False" />
    27.     <meta-data android:name="android.max_aspect" android:value="2.1" />
    28.   </application>
    29.   <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="25" />
    30.   <uses-permission android:name="android.permission.INTERNET" />
    31.   <uses-permission android:name="com.android.vending.BILLING" />
    32.   <!-- Indicates use of Android's VR-mode, available only on Android N+ -->
    33.  <uses-feature android:name="android.software.vr.mode" android:required="false" />
    34.  <!-- Indicates use of VR features that are available only on official "VR-ready" devices -->
    35.  <uses-feature android:name="android.software.vr.high_performance" android:required="false" />
    36.  <uses-feature android:glEsVersion="0x00020000" />
    37.  <uses-feature android:name="android.hardware.vulkan" android:required="false" />
    38.  <uses-feature android:name="android.hardware.gamepad" android:required="false" />
    39.  <uses-feature android:name="android.hardware.vr.high_performance" />
    40.  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    41.  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
    42.  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
    43. </manifest>

    Again this is proving: Try not to import any VR plugins, use those bundled with unity. The unity manifest generator must search entire project directory tree for any plugins suitable for Android.

    There will be some time in the future when we just write game using unity XR api and wont need to bother importing various SDKs, that will be cool. Until then we will have to muddle through ourselves.
     
    Last edited: Oct 31, 2017
    vivalavida likes this.
  18. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,408
    I had made a cross platform input plugin for both platforms that never got released because the daydream sales were a lot less than gear vr (tiny fraction, enough over it's life where it wouldn't justify support). In the end the daydream version was deprecated and the cross platform one I stopped work on, to concentrate on just the gear vr product.

    The cross platform piece of it was complete and I tried a few things, but in the end what seemed to work the best was to do everything pre build. That way you had complete control over the pipeline and could change any settings, manifests, etc. that you wanted automatically. Basically, you'd just create a few entries in your own custom menu dropdown in the editor, one for "build gear vr" and one for "build daydream". This would be the hook you need to do things pre build and then build. That way building for the various platforms is as simple as just selecting the right menu item, similar to how "build" and "build and run" are separate items. You could even extend this to 4 items one pair for debug builds and another pair for publishing builds.

    Obviously there are many ways to approach it, but this worked best for me. It's a shame daydream doesn't seem to be gaining much traction, and with go around the corner, I'm not sure it's going to get better. Hope it does though, it's a nice platform (and I've played with them all). Lack of sales was one thing, but google seems to have a bad habit of introducing breaking changes in their API (happened once at 1.4 and again at 1.6). Eventually that will be mute when Unity inputtracking and VR camera options are complete but that's a ways off.
     
    Last edited: Nov 1, 2017
    SiliconDroid likes this.
  19. vivalavida

    vivalavida

    Joined:
    Feb 26, 2014
    Posts:
    83
    @SiliconDroid
    What do you mean by this?
     
  20. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,408
    He meant it would be awesome if Unity's auto generated manifest actually took into account the appropriate entries for daydream or gear vr based on which sdk's were selected or at the top of your xr sdk list. That way you wouldn't have to provide your own to use instead of the one Unity normally includes.
     
  21. vivalavida

    vivalavida

    Joined:
    Feb 26, 2014
    Posts:
    83
    Oh, thanks,

    I assumed that he had already figured out a way to do this.

    And as of now I've taken the approach suggested by you, I've created an Editor Build script and have created two AndroidManifest.xml files(one for daydream and one for GearVR),they are in all aspects similar, just that the 'activity' section is modified depending on the platform.These are placed in my own folder (not of type Plugins) and will get swapped and put into the Asets/Plugins/Android folder before the build process.

    [if anyone's wanting to do this, have a look at OVR/Editor/OVRManifestPreprocessor.cs to give you solid start
    (comes with the Oculus Plugin)]

    (To get the initial basic manifest, just delete the Assets/Plugins/Android/AndroidManifest.xml if present, and let it build for Daydream, create a buiild, then without closeing unity head over to the project root /Temp/StagingArea/AndroidManifest.xml and copy it)

    Only pain would be manually changing the Version Code and Number for each update(the change will have to be made in both the custom manifest scripts), wish there was a way to automate this too.

    After the manifest files are swapped out I run the Build Player Pipeline as shown here.

    Tip: Use this to avoid having to set the scenes in build manually
    Code (CSharp):
    1. buildPlayerOptions.scenes = EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes);
    Any suggestions for improvements are most welcome.
     
    SiliconDroid likes this.
  22. greggtwep16

    greggtwep16

    Joined:
    Aug 17, 2012
    Posts:
    1,408
    Obviously it would take some work but you could via editor script modify the manifest text for version code and number (didn't do this but you could certainly read/change/update the file). As far as the scenes go you can via script add the scenes as well if you didn't want it to be the active list.
     
    SiliconDroid likes this.
  23. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    Great info @greggtwep16 @vivalavida, I will use methods as you mention, to force correct manifest, when I come to publish. (have bookmarked this thread).

    Thinking more about this: there is no reason for Unity to allow multiple VR SDKs to exist in the XR player settings list. I think Unity should only allow one VR SDK to be selected for any one build process. After all: any derived .apk/.exe will only work on one VR platform. And Unity could then produce a good clean build for each specified target.

    Thinking of the future:

    Will we get a universal XR API with no need to import stuff?

    Here's my wishlist for unity:
    • We code against one Unity API (XR).
    • We are able to read HMD pose through it.
    • We are able to query any VR input device through it, using some superset API.
    • We write one codebase, choose our build target and press "build".
    The API input interface, hypothetical, might be like:
    Code (CSharp):
    1. int iDevices = XR.GetNumInputDevices();
    2.  
    3. XR.InputDevice oDev = XR.GetInputDevice(0);
    4.  
    5. bool bYes = oDev.HasTrackingRot();
    6. Quaternion qRot = oDev.GetTrackingRot();
    7.  
    8. bool bYes = oDev.HasTrackingPos();
    9. vector3 vpos = oDev.GetTrackingPos();
    10.  
    11. int iJoys = oDev.GetNumJoysticks();
    12. XR.InputDevice.Joystick oJoy = oDev.GetJoystick(0);
    13. vector2 vJoy = oJoy.GetJoystickVal();
    14.  
    15. int iBtns = oDev.GetNumButtons();
    16. XR.InputDevice.Button oBtn = oDev.GetButton(0);
    17. float fPressed = oBtn.GetPressed();//return 0.0f ... 1.0f (digital or analog);
    18.  
     
    Last edited: Nov 4, 2017
    WendelinReich and vivalavida like this.
  24. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    185
    Totally agree - but this is essentially Unity's business model, the kind of abstraction and simplification they talk about at the beginning of each keynote, so I'm sure they're on it...

    What is less obvious is how platform owners (Google and Oculus here) support Unity's API standardization effort. Unity wouldn't have to standardize APIs if platforms coordinated themselves more when they define their APIs.
     
    SiliconDroid likes this.
  25. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    Yes, you're right of course, it will no doubt become unified XR API, I'm just impatient, but very grateful for the already great work done by Unity.

    Yes, for full XR (augmented reality also) API internal wiring may become complex, and Unity/VRProviders ought to agree to some standard. I can see that taking some years.

    But I'm not sure it's too big an issue if we consider VR only.
    Total information flow required for unified VR only API is:

    Input:

    Controllers

    This is the bulk of the work.
    A dynamic super-set class that will handle any input controller setup.
    All controllers are just combos of these 4 core input types:
    • 1D input device (digital button / analog trigger)
    • 2D input device (touchpad or stick)
    • 3D tracked pos
    • 3D tracked rot

    Any further abstraction can and should be built by community (or VR platform owner) on top of unity XR API using c# script/prefab, i.e. prefabs to drop in working controllers that hook into IK rigs etc.
    Code (CSharp):
    1. int iDevices = XR.GetNumInputDevices();
    2.  
    3. XR.InputDevice oDev = XR.GetInputDevice(0);
    4.  
    5. bool bYes = oDev.HasTrackingRot();
    6. Quaternion qRot = oDev.GetTrackingRot();
    7.  
    8. bool bYes = oDev.HasTrackingPos();
    9. vector3 vpos = oDev.GetTrackingPos();
    10.  
    11. int iJoys = oDev.GetNumJoysticks();
    12. XR.InputDevice.Joystick oJoy = oDev.GetJoystick(0);
    13. vector2 vJoy = oJoy.GetJoystickVal();
    14.  
    15. int iBtns = oDev.GetNumButtons();
    16. XR.InputDevice.Button oBtn = oDev.GetButton(0);
    17. float fPressed = oBtn.GetPressed();//return 0.0f ... 1.0f (digital or analog);
    18.  

    Output:

    Rendering:

    Unity already wires engine output to platform spec.
    No exposure needed via API to Unity user, no extra work on top of what has already been done.
    If a synthetic stereo view is needed in the editor then unity can just synthesize it, having simple lookup for any HMD type selected.

    Haptics:
    Simple:
    Code (CSharp):
    1.  
    2. XR.InputDevice oDev = XR.GetInputDevice(0);
    3. if(oDev.hasHapticOutput)
    4. {
    5.     oDev.DoHapticOutput(fAmplitude, fForSeconds);
    6. }
    7.  
     
    Last edited: Nov 4, 2017
    scvnathan likes this.
  26. HamFar

    HamFar

    Joined:
    Nov 16, 2014
    Posts:
    73
    In Unity 2017.2.0f3 I still get the following log warnings twice per frame. I wonder if this is only because I don't actually have a Gear VR attached?

    ovrp_GetAppHasInputFocus return Failure_NotInitialized
     
  27. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    287
    Yes, using newer oculus scripts you get that in editor mode. you can comment out the line that generates that log warning spam, double click the log inspector bottom pane to jump to said line in vis studio.
     
    HamFar likes this.
  28. Cleverlie

    Cleverlie

    Joined:
    Dec 23, 2013
    Posts:
    128
    hi guys, I just wanted to know if due to the most recent unity updates (I'm starting to use 2018.1) did you have any improvement in handling various VR platforms in a single project? any improvement regarding the unified API for everything that @SiliconDroid dreams about?

    I want to adapt a project that was originally made for PC with mouse/keyboard, I need to make it work for both Cardboard (or Daydream) and Oculus Rift, meaning that I want to reuse the maximum possible and just make a wrapper or switcher between the gvr api and prefabs and the ovr api and prefabs.

    Also I'm aware that, unlike the post above, I want to build to android cardboard/daydream and also to windows oculus rift. So I have to manually change the target platform, but I'm not aware of how complex it is to make both platforms live together in the same project, you talk a lot about gearVR and cardboard, but not PC-OculusRift and cardboard so that's why I'm asking.

    thanks for any answer!