Hey guys, I've looked all over the place and I haven't found a clear solution for this.
My requirement is simple:
-Implement a simple HUD (3 status icons) that are camera locked (follow player around) and that behave like a "ordinary" HUD (rendered always on top of everything else).
On normal dev, these would be GUI elements, however on VR I'm having a bit of trouble to make them work. I've tried all the tricks I've seen on the web.
These won't even render:
-Using Quads+OVROverlay -Canvas in Cameraspace
This one works, but the end-result is not what I need:
-Canvas in Worldspace -Planes+unlit textures
For all the interactive UI stuff I'm rendering elements on worldspace, using a gaze cursor and it works great, but these three are supposed to be always present and don't get "blocked" or "under" the world's elements, so I need them to behave like ordinary UI elements. How do I implement this?
I'm using Unity 5.2.2f1, Runtime 0.8 and a DK2.
Any help is most welcome, since I wanted to avoid any unnecessary code/unity butchery or "clever coding" 🙂
You should probably reconsider those design choices, being able to see a UI element that should be occluded but isn't can cause eye strain due to depth conflict. Consider the assumption that the information needs to always be visible, why not just place it in a convenient place in the world that can be checked with a glance? This is one of those cases where good VR design is different from good video game design, and also where not being constrained to a little rectangle invalidates some old conventions.
If you absolutely must do it though, you will need to write your own shader. The important thing is the ZTest parameter, disabling it will cause the shader to ignore any occluders.
I get what you are saying and I've followed that rule for the remaining UI (menus, buttons, etc.).
However, on this specific requirement, I need to provide the user with a status indication at all times without having him looking for it or having it hidden behind things whenever the player moves around.
Thus the need for a "old-fashion" HUD element that is allways there and never gets occluded.
The item in question is a set of three small symbols on the HUD that are discreet enough to not be in anyway invasive.
Isn't there a more simple way to implement this? I just need a classic unity GUI component, like an image.
Sorry if this sounds like pure ignorance, but is it really necessary to add my elements as quads, planes or whatever geos, position them on the world, parent them to my camera and write a shader to avoid them being occluded by other objects?
At a glance it seems a bit like "over-engineering" something that should be simpler and cleaner (considering that I am using Unity). Or am I missing something?
Can you elaborate a bit more on this strange affair of UI element representation under Unity with VR and what is the issue with this UI component limitation?
Thanks for all the help! Any pointers on this are also most welcome!
It is necessary, because you don't really have the concept of a screen anymore (and certainly no orthographic projection), no 2D plane you can draw stuff to unless you add one yourself. Even if it is stuck to the user's head, you need to position it somewhere in 3D space, there is no way around it.
If you use the new Unity UI system, you can create a world space canvas. The Oculus SDK also includes samples using the old GUI system.
The Canvas in camera space should work, I've done it before. I believe that is what you want, as long as you understand that there will be stereoscopic disparities when 3D objects come close to the camera.
Try a diff approach.. you can use the GUI tools if you want..but for this Id just create a 3d object or even just a quad and parent it to the player\camera. Position it where you want in 3d space relative to the player.
What you will want is a material with a shader that ignores z depth for rendering. I simply copied the default shader and made a couple of one line changes and it worked for me. You can then swap out the texture of that material at runtime with new graphics etc.
FYI: If its just text data then you can use the Text Mesh 3d object and it will by default render on top of everything else.
If you go UI element, then set the canvas to world, and SCALE IT WAY DOWN, like x100 times.. it starts out so big that you might not even notice that you created a canvas, took me a bit to realize that I needed to scale the canvas down to see it..
I think I'll have to go through the shader route, since I really need to get those status displays visible to the player at all times.
They will work in a AR sort of way, as for the rest of the UI, I've done some work on embedding it on the world and the results are quite interesting. Also, player feedback is very positive, which is allways good.
I'll report back when I have news regarding this. However I'm open to ideas regarding the implementation of this 😉