- Home /
The question is answered, right answer was accepted
Can't get UI Canvas to overlay the scene
I am creating a UI canvas via script and am trying to create a side bar that will overlay the screen during gameplay, but when I set the canvas render mode to "Screen Space - Overlay" it does not overlay the scene at all, and simply sticks the UI in the world space. The "Screen Space - Camera" render mode works correctly, but when using this mode I encountered a lot of clipping issues that the Overlay mode would prevent if I can get it to work.
Here is the code I use to create the UI canvas and the side bar:
// Create the canvas.
canvas = new GameObject("Battle UI Canvas", typeof(RectTransform));
canvas.transform.position = new Vector3(canvas.transform.position.x, canvas.transform.position.y, canvas.transform.position.z - 1.0f);
canvas.AddComponent<Canvas>();
canvas.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
canvas.GetComponent<Canvas>().worldCamera = Camera.main;
canvas.GetComponent<Canvas>().planeDistance = 5.2f;
canvas.AddComponent<CanvasScaler>();
canvas.GetComponent<CanvasScaler>().uiScaleMode = UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvas.GetComponent<CanvasScaler>().referenceResolution = new Vector2(Screen.width, Screen.height);
canvas.GetComponent<CanvasScaler>().matchWidthOrHeight = 0.5f;
canvas.AddComponent<GraphicRaycaster>();
// Create the side bar
int sideBoxHeight = (int)(Screen.height * 1.5);
int sideBoxWidth = (int)(Screen.width * 0.170);
GameObject sideBoxLeft = new GameObject("UI Box Left");
SpriteRenderer boxLeft = sideBoxLeft.AddComponent<SpriteRenderer>();
var mTexture = new Texture2D(sideBoxWidth, sideBoxHeight);
Color[] myColours = new Color[sideBoxWidth * sideBoxHeight];
for (int j = 0; j < (sideBoxWidth * sideBoxHeight); j++) { myColours[j] = Color.gray; }
mTexture.SetPixels(myColours);
mTexture.Apply();
Sprite mSprite = Sprite.Create(mTexture, new Rect(0.0f, 0.0f, mTexture.width, mTexture.height), new Vector2(0.5f, 0.5f), 100.0f);
boxLeft.sprite = mSprite;
boxLeft.transform.localScale += new Vector3(69.0f, 69.0f, 69.0f);
sideBoxLeft.AddComponent<RectTransform>();
sideBoxLeft.GetComponent<RectTransform>().anchoredPosition = new Vector2(-(Screen.width / 2.0f) + (sideBoxWidth / 3.0f), 0);
sideBoxLeft.transform.SetParent(canvas.GetComponent<Canvas>().transform, false);
And here is the result:
Instead of overlaying the scene the side bar is created in the same plane as the game objects and is massive. I don't understand why this is happening, as it displays correctly when the render mode is set to "Screen Space - Camera".
If anyone can point out what I am doing wrong I would really appreciate it!
Answer by hexagonius · Aug 30, 2017 at 02:46 AM
It is world space which means it's following the rules of depth testing. If you pull the canvas up a little it will look fine. Right now it's at the exact same height as the other grey sprite. That's called z-fighting, it's not clear what's closer to the camera. Either use separate camera that render your UI and the grey rectangle one after the other, or make sure they're on differing heights.
It shouldn't be world space, I deliberately set it it to the "Screen Space - Overlay" render mode because I want it to act as an overlay. You can see in the image and code that this is the mode it is set to.
If I simply increase the height of the canvas the bar is still massive, in the wrong place and at the wrong angle. It's supposed to be a thin grey bar on the left hand side of the screen (and it is, if I set the render mode to "Screen Space - Camera").
But I don't want the UI to exist in the world space at all because of clipping issues with other game objects when the camera is zoomed in. I want it to function as an overlay.
So you're saying UI Box left is the grey rectangle that's rendered from the camera? Could you turn the camera off and tell what's visible then? A screen space overlay must work without any camera whatsoever
Answer by Ianamus · Aug 30, 2017 at 08:52 PM
Right, I've found the issue. The UI elements I'm trying to add to the canvas are using sprite renderers, which aren't supposed to be used for UI elements. Changing them to Image instead fixes this.
Follow this Question
Related Questions
Screen Space - Camera to Screen Space - Overlay switch issue 0 Answers
Why use different Canvas Render Modes 0 Answers
Scaling panel by different screen sizes 1 Answer
Universal Method of finding pixel dimensions of UI elements 1 Answer
How to scale according to different mobile resolutions? 0 Answers