All Oculus Quest developers MUST PASS the concept review prior to gaining publishing access to the Quest Store and additional resources. Submit a concept document for review as early in your Quest application development cycle as possible. For additional information and context, please see Submitting Your App to the Oculus Quest Store.
This section provides guidelines to help your Unity Android app performance.
Good performance is critical for all VR applications, but the limitations inherent to standalone development warrant special consideration.
This section describes recommended targets and settings for Android projects.
Be conservative on performance from the start.
Keep the total number of draw calls to a minimum. A conservative target would be less than 100 draw calls per frame.
Unity provides several built-in features to help reduce draw calls such as batching and culling.
Unity attempts to combine objects at runtime and draw them in a single draw call. This helps reduce overhead on the CPU. There are two types of draw call batching: Static and Dynamic.
Static batching is used for objects that will not move, rotate or scale, and must be set explicitly per object. To mark an object static, select the Static checkbox in the object Inspector.
Dynamic batching is used for moving objects and is applied automatically when objects meet certain criteria, such as sharing the same material, not using real-time shadows, or not using multipass shaders. More information on dynamic batching criteria may be found here: https://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html
Unity offers the ability to set manual per-layer culling distances on the camera via Per-Layer Cull Distance. This may be useful for culling small objects that do not contribute to the scene when viewed from a given distance. More information about how to set up culling distances may be found here: https://docs.unity3d.com/Documentation/ScriptReference/Camera-layerCullDistances.html.
Unity also has an integrated Occlusion Culling system. The advice to early VR titles is to favor modest “scenes” instead of “open worlds,” and Occlusion Culling may be overkill for modest scenes. More information about the Occlusion Culling system can be found here: https://docs.unity3d.com/Manual/OcclusionCulling.html.
Keep geometric complexity to a minimum. 50,000 static triangles per-eye per-view is a conservative target.
Verify model vert counts are standalone-friendly. Typically, assets from the Asset Store are high-fidelity and will need tuning for standalone.
Unity provides a built-in Level of Detail system, allowing lower-resolution meshes to be displayed when an object is viewed from a certain distance. For more information on how to set up a LODGroup for a model, see the following: https://docs.unity3d.com/Documentation/Manual/LevelOfDetail.html
Verify your vertex shaders are standalone friendly. And, when using built-in shaders, favor the Mobile or Unlit version of the shader.
Be mindful of Game Object counts when constructing your scenes. The more Game Objects and Renderers in the scene, the more memory consumed and the longer it will take Unity to cull and render your scene.
Pixel Complexity: Reduce per-pixel calculations by baking as much detail into the textures as possible. For example, bake specular highlights into the texture to avoid having to compute the highlight in the fragment shader.
Verify your fragment shaders are standalone friendly. And, when using built-in shaders, favor the Mobile or Unlit version of the shader.
Overdraw: Objects in the Unity opaque queue are rendered in front to back order using depth-testing to minimize overdraw. However, objects in the transparent queue are rendered in a back to front order without depth testing and are subject to overdraw.
Avoid overlapping alpha-blended geometry (e.g., dense particle effects) and full-screen post processing effects.
Android devices are typically constrained by the processing power of the device and its ability to dissipate heat.
Android devices can manage the heat and their power consumption using the Fixed Clock Level API on Gear VR and Dynamic Clock Throttling. A detailed overview of these two features is available on the Power Management page in the Mobile SDK guide.
To set your clock level in Unity apps, set
OVRManager.cpuLevel ( ) and
OVRManager.gpuLevel ( ).
This section describes best practices for Android projects.
This section describes startup sequence recommendations and mandatory behaviors required for standalone applications.
For good VR experiences, all graphics should be rendered such that the user is always viewing a proper three-dimensional stereoscopic image. Additionally, head-tracking must be maintained at all times. We recommend considering using a cubemap overlay for your startup screen (see VR Compositor Layers), which will render at a consistent frame rate even if the application is unavailable to update the scene.
An example of how to do this during application start up is demonstrated in the SDKExamples Startup_Sample scene:
For more information about the Oculus reserved interactions, see Universal Menu and Reserved User Interactions in our Mobile Developer Guide.
See the class description of OVRPlatformMenu in our Unity Scripting Reference for details about the relevant public members.
The volume buttons are reserved, and volume adjustment on the Samsung device is handled automatically. Volume control dialog is also handled automatically by the VrApi as of Mobile SDK 1.0.3, supported by Utilities for Unity versions 1.5.0 and later. Do not implement your own volume handling display, or users will see two juxtaposed displays.
It is possible to override automatic volume display handling by setting VRAPI_FRAME_FLAG_INHIBIT_VOLUME_LAYER as an ovrFrameParm flag.