Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Having GUI elements in front of *everything* ?

Discussion in 'UGUI & TextMesh Pro' started by Foxxis, Aug 22, 2014.

  1. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Hi,

    Is there a simple way in the new UI to make sure a screen space canvas is always rendered in front without using additional cameras?
    This is important when dealing with a HUD-like UI for Rift-enabled games where you want to rely on the Rift cameras for rendering the screen space UI as well.
    With NGUI we would customise the shader used, but I am not sure if that is possible with uGUI or if there is a parameter or sorting mode that can be set?

    Thanks in advance!
     
  2. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,370
    It's possible to assign a custom material to a UI.Graphic, and that custom material can have a shader that does what you want.

    However in your situation I'd probably just use World Space Canvas as a child of the OVRController, and then add extra cameras to each eye position to clear depth and render it, and hack/change whatever's needed in the OVR kit to make it render those extra camera prior to doing all the lens distortion processing.
     
    Bodrp likes this.
  3. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Thank! Well, we want to avoid extra cameras among other things to be able to avoid modifying the Oculus code too much since it is still very much a moving target. I had hoped the new GUI would have some way of forcing it to always draw on top since I can imagine other situations it might be useful besides VR...
     
  4. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,370
    It's trivial to have the GUI always draw on top for a single camera - you just put the Canvas in Overlay mode - but I think it won't be so easy for Rift projects because you need it to draw for two cameras.
     
  5. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    With NGUI this was trivial as all GUI elements were regular geometry. According to the cross post on the QA thread, sorting layers might help but I need to read up on them in the docs and how a screen space canvas is rendered by multiple cameras (do a canvas bind to a certain camera?). Too ignorant at the moment. :)
     
  6. geff

    geff

    Joined:
    Mar 3, 2013
    Posts:
    27
    You can use multiple canvas with the new UI.
    Each canvas has a sorting layer and a layer order.

    You can also set your front GUI at the bottom of the canvas hierarchy
     
  7. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Sure, but is one canvas visible to all cameras? Ie. if you have a world space canvas, will both the OR cameras render that canvas? If so, the only thing needed is to make sure that canvas is rendered above everything - which might be possible with sorting (according to Unity in the QA thread, have to read the docs on it though).
     
  8. geff

    geff

    Joined:
    Mar 3, 2013
    Posts:
    27
    Canvas have 3 Render Modes :

    - Screen space - Overlay : No need of any camera to render the Canvas. Child elements of the Canvas are render on top of all other Camera rendering.

    - Screen space - Camera : You have to set a rendering Camera. This camera's Culling Mask must contain the canvas layer (in general named UI). Only this camera can render the canvas, even if you set UI in the culling mask of an other Camera.

    - World space : You have to set a rendering Camera. This camera's Culling Mask must contain the canvas layer (in general named UI). One of the difference with Screen space - camera is that each Camera that contain Canva's layer render this canvas. But the events (click, drag, etc...) are captured from the Camera set in the Canvas Event Camera.

    if you want to be sure that your GUI is rendered on top of all other render, three options :
    - Set Screen space Overlay in the canvas
    - or change the Depth property of the camera rendering your UI. You can composite your final image on screen with multiple camera rendering differents parts of your scene (with specific cullin mask) and by playing with the depth property.
    - or play with Sorting Layer / Order in layer of canvas.

    I'm using Unity 4.6 beta since two months, new UI is a real great tool.
    I hope my explanations are clear and my english not too approximative.

    #geff
     
    AdamanSpark and OP_toss like this.
  9. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Thanks for your reply, but I was well aware of those options.

    The problem is that they are not good enough. With NGUI the solution was very simple: use another shader for the UI elements. Like I stated earlier: I am looking for a similar solution here, one that allows for world space UI elements that render in front of all objects - without additional cameras.
    If it is not currently possible, I hope Unity will recognise the need for shader customisation. Having 2 extra cameras for a VR UI solution is not a practical or elegant solution.
     
  10. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,370
     
  11. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Nope. The custom shader tags seems to be ignored. Pulling the same trick as we did with NGUI (forcing render in the overlay queue) has no effect. I frankly think it is a bit embarrassing that it is impossible to get a good answer re. this question from Unity. Frustrating.
     
  12. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    The shader was not ignored, but the Z-testing was done in a special mode for the GUI. Switching to ztest always solved the issue. So, render queue overlay + ztest always does indeed work on GUI objects with a custom shader. That is the way to go if you need a HUD-like overlay drawn at comfortable distance for use with Rift/VR without adding two additional UI cameras.

    Thanks to those who provided suggestions along the way.
     
    Last edited: Aug 24, 2014
    superpig likes this.
  13. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,160
    Hi Foxxis,

    So the way I would recommend setting up a UI for this would be:
    • World space UI, both cameras set to render the UI.
    • The canvas parented to the cameras in a way that it moves with them nicely
    • Use RenderLayers to have the canvas render after everything else in the scene
    • Custom shader to change the ztest mode (It probably makes sense for us to expose the z-test option on the canvas itself... it would have default (unity decides), then the standard options... then no custom shader would be required.
    If you are going to be using pointer (mouse ect, eye tracking) input then you will need to probably write a custom input module to do correct handling this also as right now it's designed to work with a singular camera.
     
    isidro02139 likes this.
  14. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Thanks Tim!
    We actually got away with using raycasting from one camera POV with NGUI. It felt accurate enough in the rift. We'll see how things work out with uGUI. However, implementing custom input modules looks easy, so that should not be a problem. Kudos for the open sourcing you are doing!
     
  15. JAKJ

    JAKJ

    Joined:
    Aug 17, 2014
    Posts:
    185
    Yes, it would be very helpful to have the ability to say "I want this UI element to be shown but completely ignored otherwise.". I'm running into issues where, if I have a tooltip that pops up over a button and it slightly overlaps, if the mouse is in the overlap, every time the tooltip obscures the button at that small spot it will make the button lose its "mouse is over you" status and the tooltip disappears, and so it starts strobing.
     
  16. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,370
    Your tooltip object just needs a component with ICanvasRaycastFilter implemented on it, set up to return false from IsRaycastLocationValid. That'll cause it to be ignored when raycasting, such that the mouse will never be 'over' it.
     
  17. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,160
    Or add a canvas group and turn off 'blocks raycasts'
     
  18. JAKJ

    JAKJ

    Joined:
    Aug 17, 2014
    Posts:
    185
    Y'know, that's what's so glorious about Unity: It's like a giant box of legos and you put them together however best suits.
     
    superpig likes this.
  19. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,961
    Any idea if this is ever going to be implemented?
     
  20. JAKJ

    JAKJ

    Joined:
    Aug 17, 2014
    Posts:
    185
    I'd rather them not be implementing new features at this point, because every new feature comes with new bugs. 4.6 needs to occur at *some* point.
     
    phil-Unity likes this.
  21. ForceX

    ForceX

    Joined:
    Jun 22, 2010
    Posts:
    1,102
    +1 to exposed Z test for the Canvas UI
     
    JoeStrout and isidro02139 like this.
  22. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    I would just like to point out that the fix is simple. You just need a custom shader and material for the elements you wish to be in front. Works like a charm.

    @Tim C :
    We did only need the last step as indicated above. What would the benefit of renderlayers to make sure it renders last be? Is it to ensure the canvas is fully stationary in relation to the camera and not offset by a frame? If so I would rather have the canvas free and set via script in lateupdate to ensure it follows the camera...?
     
  23. kamoser

    kamoser

    Joined:
    Aug 24, 2015
    Posts:
    1
    So if I have a world space canvas that has Image sprites on it, according to Tim's post I think I'd write a custom shader with ZTest Always set and in C# set my material's render queue to "Overlay". However that requires writing my own Shader when I am perfectly fine with whatever shader Unity is using for sprites. That one seems to be closed source as well, I cannot find it to edit...
     
  24. GregMeach

    GregMeach

    Joined:
    Dec 5, 2012
    Posts:
    249
    Go HERE and from each platform drop-down you can select the "Built in shaders" pack for the source.
     
  25. eobet

    eobet

    Joined:
    May 2, 2014
    Posts:
    176
    Two years on, apparently not. ;)

    I was also looking for this exact feature. World space UI (because reasons) rendered on top of everything else using a single camera (because reasons)... guess the shader route is the way to go, still so I used this one, which seems popular:

    http://answers.unity3d.com/comments/1081547/view.html
     
    Last edited: Oct 31, 2017
    tbriley and JoeStrout like this.
unityunity