Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Matching Camera Viewport to Screen Space Overlay Canvas

Discussion in 'UGUI & TextMesh Pro' started by JAKJ, Sep 2, 2014.

  1. JAKJ


    Aug 17, 2014
    I'm using a "Screen Space - Overlay" canvas for my game (the whole game is menus and tiles and such like a board game, so the entire game is inside the canvas) with Reference Resolution set to 1920x1080, which keeps the canvas object in 3D space set to that size and adjusts the scaling factor. This works correctly: Narrower aspect ratios give me black bars above/below just like I want.

    However, I want to render 3D things like objects and particle systems *behind* the UI elements and have them lined up properly. However, since it doesn't work to have the 3D objects actually in the Canvas (pretty sure 3D objects can't be given a RectTransform), I can't figure out a way to get things to line up. The game automatically changes the camera's viewport ratio to match the screen's ratio which is how all of this works, so I can't just create a GameObject with the same dimensions and scaling of the Canvas, and if I switch to a world-space canvas, that'll break all the nice auto-ratio-handling. What's the real way to do this?
  2. runevision


    Nov 28, 2007
    3D objects can have a RectTransform fine, they just ignore the rect and are positioned at the pivot position of the RectTransform. Anchoring will still work.

    However, in Screen Space - Overlay mode the 3D objects will not appear in screen space unless you manually position your camera in a very specific way. I suggest you instead switch to using Screen Space - Camera. Then your 3D objects will render aligned together with the UI. They can be behind the UI if you set the plane distance in the Canvas sufficiently small.
  3. JAKJ


    Aug 17, 2014
    So then I would create a container GameObject that changes its scale to match that of the canvas each time the screen's resolution changes. That's kind of neat: It turns the entire Canvas into just a quad but Reference Resolution still seems to work.
  4. JAKJ


    Aug 17, 2014
    Just got this working flawlessly and wanted to put it here so people know.

    1) Put "Reference Resolution" on Canvas and set highest targetted resolution.
    2) Put Canvas into "Screen Space - Camera" and insert reference to main camera.
    3) Change orthographic "Size" of camera to be 1/2 the height of your reference resolution (so for 1920x1080, that's 540), and change camera position to be (0,0,0).
    4) Create empty game object at (0,0,500), or whatever z-value suits the Plane Distance of your Canvas.
    5) Put this script on something:

    Code (CSharp):
    1. using UnityEngine ;
    3. public class ScaleWorldByCanvas : MonoBehaviour
    4. {
    5.     public Transform WorldObject ;
    6.     public Transform CanvasObject ;
    8.     int CachedWidth ;
    9.     int CachedHeight ;
    11.     void Refresh ( )
    12.     {
    13.         CachedWidth = Screen . width ;
    14.         CachedHeight = Screen . height ;
    16.         WorldObject . localScale = CanvasObject . localScale ;
    17.     }
    19.     void Start ( )
    20.     {
    21.         Refresh ( ) ;
    22.     }
    24.     void Update ( )
    25.     {
    26.         if ( Screen . width == CachedWidth )
    27.         {
    28.             if ( Screen . height == CachedHeight )
    29.             {
    30.                 return ;
    31.             }
    32.         }
    34.         Refresh ( ) ;
    35.     }
    36. }
    Now, put all your 3D UI objects under that one GameObject that's being scaled, and you can position things as if one world unit is one pixel and it will remain fixed relative to the UI.
    arg_barg, krajzeg, a318 and 9 others like this.