Oculus Rift World Space Cursors for World Space Canvases in Unity 4.6

Unity 4.6 is here! (Well, in public beta form). Finally–the GUI that I’ve waited YEARS for is in my hands. Just in time, too. I’ve just started building the GUI for my latest Oculus Rift project.

The new GUI in action.

The new GUI in action from Unity’s own demo.

One of the trickiest things to do in VR is a GUI. It seems easy at first but many lessons learned from decades of designing for the web, apps, and general 2D interfaces have to be totally reinvented. Given we don’t know what the standard controls may be for the final kit, many VR interfaces at least partially use your head as a mouse. This usually means having a 3D cursor floating around in world space which bumps into or traces through GUI objects.

Unity 4.6’s GUI features the World Space Canvas–which helps greatly. You can design beautiful, fluid 2D interfaces that exist on a plane in the game world making it much more comfortable to view in VR. However, by default Unity’s new GUI assumes you’re using a mouse, keyboard, or gamepad as an input device. How do you get this GUI to work with your own custom world-space VR cursor?

The answer is the use of Input Modules. However, in the current beta these are mostly undocumented. Luckily, Stramit at Unity has put up the source to many of the new GUI components as part of Unity’s announced open source policy. Using this code, I managed to write a short VRInputModule class that uses the result of a trace from my world space VR cursor and feeds it into the GUI. The code is here. Add this behavior to the EventSystem object where the default ones are.

In my current project, I have a 3D crosshair object that floats around the world, following the user’s view direction. The code that manages this object performs a trace, seeing if it hit anything in the UI layer. I added box colliders to the buttons in my World Space Canvas. Whenever the cursor trace hits one of these objects, I call SetTargetObject in the VRInputModule and pass it the object the trace hit. VRInputModule does the rest.

Note that the Process function polls my own input code to see if a select button has been hit–and if so, it executes the Submit action on that Button. I haven’t hooked up any event callbacks to my Buttons yet–but visually it’s responding to events (highlighting, clicking etc.)

It’s quick and dirty, but this should give you a good start in building VR interfaces using Unity’s new GUI.

Unity3D 4 Pet Peeves

I’ve been updating my older apps to use the newly released Unity3D 4 engine, as well as starting an entirely new project. I haven’t used many of Unity3D 4’s new features yet, but I figured this is as good a time as any to list a few of my pet peeves with Unity3D 4 as I did with Unity3D 3 a few years back.

It’s time Unity3D had a package manager.

Unity3D plug-ins and assets purchased from the Asset Store are invaluable. It’s becoming the most important feature that makes Unity3D the superior choice. However, managing projects with multiple plug-ins is can be a nightmare. A lot of this is how Unity3D handles file deletions.

If you click the “update” button to overwrite an existing plug-in with the latest version from the Asset Store, it may wreak havoc upon your entire project. Unity3D’s file hashing system will sometimes fail to overwrite files with the same name, even if you are importing a newer one. You’ll end up with a mess of old and new plug-in files causing chaos and mayhem. The only way to prevent this is to manually find delete all the old plug-in files before updating with the latest version.

Not to mention the fact that native plug-ins either require you to manually setup your own XCode project with external libraries or have their own proprietary scripts that edit your XCode project. Unity3D should provide an API and package manager that lets plug-ins forcibly delete and update their own files as well as modify settings in the XCode project Unity3D generates.

Let me import files with arbitrary extensions.

A minor annoyance is how Unity3D will only accept files with specific extensions in your project. If you want a custom binary data file you HAVE to give it the txt extension. It’s the only way you can drag the file in to the project. Unity3D should allow you to import files with any extension you want, but provide a method in the AssetPostprocessor API to be called when an unknown file extension is detected.

Where’s the GUI?

Come on now. It’s 2013. The new GUI has been “coming soon” for years. Unity hired the NGUI guy, which leads me to believe the mythical Unity3D 4 GUI is merely the stuff of legends and fantasies. I like NGUI but I’m really looking forward to an official solution from Unity. Although I’m not looking forward to re-writing all my GUIs once it arrives. Let’s just get it over with. Bring it on.

Monodevelop sucks.

My god. Monodevelop sucks. Lots of people use other text editors for code, but you still can’t avoid touching Monodevelop when it comes to debugging on OSX. I’m sure it can be whipped into shape with a minor overhaul, but it’s been awful for so long perhaps this is unlikely. Aside from the crashes and interface weirdness, how much human productivity has been destroyed waiting for Monodevelop to reload the solution every time so much as a single file has been moved to a different folder?

Is it time to update Mono?

While we’re at it, Mono recently updated to C# 5.0. I’m not sure if this is a big performance drag or not, but I’d love to see Unity3D’s Mono implementation updated to the latest. There are some C# 5.0 features I’ve been dying to use in Unity3D.

Tough Love

Don’t take it personally, Unity3D is still my engine of choice. This list of annoyances is pretty minor compared to previous ones. Every year, Unity gives me fewer and fewer things to whine about. It seems competing solutions are having trouble keeping up.