Introduction
Virtual Reality might be the next big thing. All of the big tech companies are starting to invest in this industry, so things will surely get even more interesting in the future. Currently, virtual reality is mostly smartphone based, with additions like Google Cardboards and Samsung Gear VR currently the most popular ones. The Samsung Gear VR is definitely the more sophisticated one – it has it’s own Oculus Store. On the other hand, the Cardboards are just lenses in a cartoon with a placeholder for a smartphone, but things might change very soon when the new Google VR platform Daydream comes out this fall. So how to put a Samsung Gear VR app on the Oculus Store? Developing and shipping such an app to the store was pretty new experience, so here are the lessons learned.
Technology
Currently, there are few options to develop Samsung Gear VR apps:
- Native Mobile SDK – The first option is to develop with the native Oculus Mobile SDK, for all the C++ developers and enthusiasts.
- Unity – Unity is the most popular (and probably the best) gaming engine on the market. It has a great editor, where you can setup your scenes and game objects. The behaviour of the game objects is accomplished by adding scripts, which can be written in C#, JavaScript and Boo. It has good support for Virtual Reality and a lot of tutorials to get you started easily.
- GearVRf – Another option is Samsung’s GearVRf, which is pretty new and claims that’s intended for all of the Android developers with no gaming engine experience. The development is done in Java and you can also use most of the standard Android components while developing the UI. According to their web page it is:
– Easy-to-use Java application development environment
– Easy access to powerful VR technology
– Does not require extensive knowledge of OpenGL and the Oculus renderer
– Simple and effective rendering manager
– Compatible with mainstream VR development tools.
In a project where we must have delivered on time, the native mobile SDK didn’t look as the best option, mostly because of the learning curve (we had no professional C++ experience) and we could’ve easily get stuck, so we’ve ticked that one off straight away (although, performances would’ve been the best with this choice). We’ve given the other two (Unity and GearVRf) few days each for evaluation. Although GearVRf sounded promising at the beginning, since we could’ve reused some Android knowledge, it was really hard and slow to get it up and running. Also, the documentation and the community are still not that big, which was also a risk, so we’ve decided to go with the safer option – Unity. Most of the apps on the Oculus store are developed in Unity, which was also a plus, but not the key reason. The biggest pro Unity argument was that it’s a mature, well documented engine with big community and everything that we wanted to develop was possible with it. We just had to learn the technology and there was a lot of material for that. It turned out to be pretty good decision, since you can really quickly get into the Unity world and we’ve managed to complete the app on time.
Technical considerations
The app had to load JSON feed which also contained links to images that had to be loaded afterwards for every entry. In the mobile world, this can be done very easily, we can just put all of the image requests in the background and when they arrive just update on the main thread the corresponding views – the settings of the image is not an expensive operation.
On the other hand, there’s one big limitation in Unity – Unity is not thread safe. Using C# System.Threading is possible as long you are not interacting with Unity objects. The parts that took the most time in our app were pulling data from Internet, building textures and game objects. We could’ve only used System.Threading for the networking part, but that didn’t improve the experience much, because the rendering of the textures and game objects took a lot of time and all of that had to be done on the main thread – which reduced the frame rates significantly. And due to Oculus requirements and more importantly, pleasant user experience, apps have to run on at least 60 Hz. This meant we had to make the user wait for few more seconds until everything was loaded – we’ve added additional loading screen right after the splashscreen. When the loading screen disappeared, the app started functioning smooth and fast. Without it, the app was immediately started, but had glitches at the beginning, which was the trade-off that we were willing to make.
The Oculus Docs also support this:
“App responsiveness is important. It is okay for an app to take time to start up, but the user should not left sitting in an unresponsive headset while it happens. When an application is launched from the Oculus app or Home, it must either render the complete loaded application or a non-head-locked loading screen in VR within four seconds.”
Another thing about Unity that I’ve liked are packages. There’s an assets store, where you can download or buy a functionality and directly import it in your app – very handy for not experienced Unity developers.
Going to the Store
After you’ve developed your awesome new Gear VR app, it’s time to put it on the Oculus Store. As mentioned above, this was very new to us and we didn’t know what to expect. Therefore, we’ve submitted the app for review twenty days before our targeted release date. After you submit the app, you receive an email that the review usually takes two to three weeks. Before submitting the app, it’s really important to go through all of the Oculus Store requirements and make sure you follow them. Since VR sets can easily lead to dizzines and sickness, it’s really important for the app to perform well. Also, there’s a content check, so even if the technical requirements are satisfied, the app still might not be accepted to the store. Both Oculus and Samsung review the apps before they are accepted.
We’ve received our first response after a week – rejected! There’s a test results page on the dashboard, and we’ve failed all the tests (prompts test, reserved interactions test, functional test, graphics test and image test), except the App installation test. The message was “We could not continue this test due to a failure or crash in your app.”, which was very strange, because during development we haven’t experienced any crashes – even on the same combinations of Android OS and devices that Oculus had tested. Our app status was changed to “Changes Requested”.
We’ve created a ticket about this issue, asking how their environment is different than the Oculus release channels that we’ve used to distribute the app until then. A good thing about the release channels (Alpha, Beta, RC and Store) is that you can easily copy the same build from channel to channel after some testing. And we’ve submitted a thoroughly tested build to the Store channel for review. But we haven’t received any response on the ticket, so we were on our own. We’ve gone through the submission requirements again, changed the entitlements implementation and submitted again and again – rejected! We’ve created another ticket, we’ve also asked the community, but with no success. Then we’ve started to think that maybe they didn’t wait past the loading screen and immediately concluded the app is blocked on the loading screen.
So we’ve spent some time optimizing the startup process and submitted again, and again we were rejected, with not much details. The good thing when the app is in status “Changes Requested” is that they reply much faster. We had a spinner on the loading screen, and since that one was also on the main thread, it was sometimes blocking, which also might have led the Oculus people to think that the app is blocked. So we’ve replaced it with a text like “Loading, please wait”.
After some really exhausting ping pong match with the Oculus Review team, they have finally approved it and it was in the store, two days before our strict deadline. Was it just one thing, or all of the above improvements that led to finally accepting the app? We will never find that out. 🙂 But good thing is that at the end it was accepted and everyone was happy and relieved.