Setting the Canvas to Render itself as an Overlay on the Camera and not in World Space, seems to be the easiest fix here. Try that, if it doesn't work you will have to do something to edit the canvas through code or Masking Layers.
↧
Answer by SnStarr
↧
Answer by DanSuperGP
You're going to need a custom shader for your World Space UI objects that has it's Render Order to Overlay and has ZTest turned off.
This is a copy of the Default UI shader with the necessary changes. Should do the trick. Just make a material with this shader, and apply it to everything you want drawn over the top of geometry in your WorldSpace UI.
Shader "UI/Default_OverlayNoZTest"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue"="Overlay"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
clip (color.a - 0.01);
return color;
}
ENDCG
}
}
}
↧
↧
Answer by debeani
If you have a lot of UI elements visually attached to game elements then you are going to want to use world space. But if you want your UI to look like an overlay. You're going to want to render your game and the UI separately and then composite them together.
1. Put your UI on a Layer called UI (if it isn't already).
2. Duplicate your Main Camera and call it UI Camera.
3. Parent your UI Camera to the Main Camera.
4. Remove scripts like camera control, post effects and audio listeners from the UI Camera.
5. In the Main Camera Culling Mask turn off UI
6. In the UI Camera turn everything off but UI.
7. In the UI Camera change Clear Flags to Depth only
8. In the UI Camera change the Depth to something higher than the value on your Main Camera.
9. Then in your Canvas set the Event Camera to the UI Camera.
This image is of the Scene view
![alt text][1]
While this is what it looks like in game (please ignore the test graphics)
![alt text][2]
[1]: /storage/temp/39681-2015-01-28-09-19-49-unity-shipyardunity-murphy-sta.png
[2]: /storage/temp/39680-2015-01-28-09-20-12-unity-shipyardunity-murphy-sta.png
↧
Answer by ham1985
After Creating a world space Canvas , Set Sorting Layer To UI.
Then You will Have all Objects inside Canvas(tagged UI) On top of others.
↧
Answer by art_craft_vlad
Ok, try this one: [ui-defaultfontdrawontop.zip][1]
The shader from DanSuperGP had a bug in it which was messing up the colors. This is a copy of UI/Default Font shader which only needed one thing fixed: ZTest set to 'off'.
. . . . . . . .
EDIT: for some reason ZIPs are forbidden.
Here is the complete text:
Shader "UI/Default Font Draw On Top" {
Properties {
_MainTex ("Font Texture", 2D) = "white" {}
_Color ("Text Color", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
}
SubShader {
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Lighting Off
Cull Off
ZTest Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform fixed4 _Color;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = v.color * _Color;
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
#ifdef UNITY_HALF_TEXEL_OFFSET
o.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = i.color;
col.a *= tex2D(_MainTex, i.texcoord).a;
clip (col.a - 0.01);
return col;
}
ENDCG
}
}
}
↧
↧
Answer by Darioszka
In Canvas obiects (sprites) when I set material to Sprite-Defaults UI is behind objects in scene. When I click material to None in editor is no change but when I click Play UI is before evertyhing.
I don't check this on mobile.
↧
Answer by Xomo
If you render everything yall be rendering youself mate. Be sure to get Donald trumps hair.
↧
Answer by SnStarr
Setting the Canvas to Render itself as an Overlay on the Camera and not in World Space, seems to be the easiest fix here. Try that, if it doesn't work you will have to do something to edit the canvas through code or Masking Layers.
↧
Answer by DanSuperGP
You're going to need a custom shader for your World Space UI objects that has it's Render Order to Overlay and has ZTest turned off.
This is a copy of the Default UI shader with the necessary changes. Should do the trick. Just make a material with this shader, and apply it to everything you want drawn over the top of geometry in your WorldSpace UI.
Shader "UI/Default_OverlayNoZTest"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue"="Overlay"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
clip (color.a - 0.01);
return color;
}
ENDCG
}
}
}
↧
↧
Answer by debeani
If you have a lot of UI elements visually attached to game elements then you are going to want to use world space. But if you want your UI to look like an overlay. You're going to want to render your game and the UI separately and then composite them together.
1. Put your UI on a Layer called UI (if it isn't already).
2. Duplicate your Main Camera and call it UI Camera.
3. Parent your UI Camera to the Main Camera.
4. Remove scripts like camera control, post effects and audio listeners from the UI Camera.
5. In the Main Camera Culling Mask turn off UI
6. In the UI Camera turn everything off but UI.
7. In the UI Camera change Clear Flags to Depth only
8. In the UI Camera change the Depth to something higher than the value on your Main Camera.
9. Then in your Canvas set the Event Camera to the UI Camera.
This image is of the Scene view
![alt text][1]
While this is what it looks like in game (please ignore the test graphics)
![alt text][2]
[1]: /storage/temp/39681-2015-01-28-09-19-49-unity-shipyardunity-murphy-sta.png
[2]: /storage/temp/39680-2015-01-28-09-20-12-unity-shipyardunity-murphy-sta.png
↧
Answer by ham1985
After Creating a world space Canvas , Set Sorting Layer To UI.
Then You will Have all Objects inside Canvas(tagged UI) On top of others.
↧
Answer by art_craft_vlad
Ok, try this one: [ui-defaultfontdrawontop.zip][1]
The shader from DanSuperGP had a bug in it which was messing up the colors. This is a copy of UI/Default Font shader which only needed one thing fixed: ZTest set to 'off'.
. . . . . . . .
EDIT: for some reason ZIPs are forbidden.
Here is the complete text:
Shader "UI/Default Font Draw On Top" {
Properties {
_MainTex ("Font Texture", 2D) = "white" {}
_Color ("Text Color", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
}
SubShader {
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Lighting Off
Cull Off
ZTest Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform fixed4 _Color;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = v.color * _Color;
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
#ifdef UNITY_HALF_TEXEL_OFFSET
o.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = i.color;
col.a *= tex2D(_MainTex, i.texcoord).a;
clip (col.a - 0.01);
return col;
}
ENDCG
}
}
}
↧
Answer by Julien-Lynge
The previous answers basically involve you copying Unity's built-in UI shader and then overriding the ZTest value. Unity actually built the UI shaders with ShaderLab named values, meaning you can solve this with just a line of code. That way, you can always use Unity's latest shaders without having to hard code anything.
Here's an example script that allows you to test the code in the editor. Just attach it to your Image and hit 'apply' in the inspector.
In a nutshell, I'm just making a copy of Unity's default rendering material, then changing the value of ZTest on the copy, then applying it back to the Image. This will work for any UI graphic - text, etc.
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode]
public class CustomRenderQueue : MonoBehaviour {
public UnityEngine.Rendering.CompareFunction comparison = UnityEngine.Rendering.CompareFunction.Always;
public bool apply = false;
private void Update()
{
if (apply)
{
apply = false;
Debug.Log("Updated material val");
Image image = GetComponent
();
Material existingGlobalMat = image.materialForRendering;
Material updatedMaterial = new Material(existingGlobalMat);
updatedMaterial.SetInt("unity_GUIZTestMode", (int)comparison);
image.material = updatedMaterial;
}
}
}
↧
↧
Answer by SnStarr
Setting the Canvas to Render itself as an Overlay on the Camera and not in World Space, seems to be the easiest fix here. Try that, if it doesn't work you will have to do something to edit the canvas through code or Masking Layers.
↧
Answer by DanSuperGP
You're going to need a custom shader for your World Space UI objects that has it's Render Order to Overlay and has ZTest turned off.
This is a copy of the Default UI shader with the necessary changes. Should do the trick. Just make a material with this shader, and apply it to everything you want drawn over the top of geometry in your WorldSpace UI.
Shader "UI/Default_OverlayNoZTest"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue"="Overlay"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
clip (color.a - 0.01);
return color;
}
ENDCG
}
}
}
↧
Answer by debeani
If you have a lot of UI elements visually attached to game elements then you are going to want to use world space. But if you want your UI to look like an overlay. You're going to want to render your game and the UI separately and then composite them together.
1. Put your UI on a Layer called UI (if it isn't already).
2. Duplicate your Main Camera and call it UI Camera.
3. Parent your UI Camera to the Main Camera.
4. Remove scripts like camera control, post effects and audio listeners from the UI Camera.
5. In the Main Camera Culling Mask turn off UI
6. In the UI Camera turn everything off but UI.
7. In the UI Camera change Clear Flags to Depth only
8. In the UI Camera change the Depth to something higher than the value on your Main Camera.
9. Then in your Canvas set the Event Camera to the UI Camera.
This image is of the Scene view
![alt text][1]
While this is what it looks like in game (please ignore the test graphics)
![alt text][2]
[1]: /storage/temp/39681-2015-01-28-09-19-49-unity-shipyardunity-murphy-sta.png
[2]: /storage/temp/39680-2015-01-28-09-20-12-unity-shipyardunity-murphy-sta.png
↧
Answer by ham1985
After Creating a world space Canvas , Set Sorting Layer To UI.
Then You will Have all Objects inside Canvas(tagged UI) On top of others.
↧
↧
Answer by art_craft_vlad
Ok, try this one: [ui-defaultfontdrawontop.zip][1]
The shader from DanSuperGP had a bug in it which was messing up the colors. This is a copy of UI/Default Font shader which only needed one thing fixed: ZTest set to 'off'.
. . . . . . . .
EDIT: for some reason ZIPs are forbidden.
Here is the complete text:
Shader "UI/Default Font Draw On Top" {
Properties {
_MainTex ("Font Texture", 2D) = "white" {}
_Color ("Text Color", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
}
SubShader {
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Lighting Off
Cull Off
ZTest Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform fixed4 _Color;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = v.color * _Color;
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
#ifdef UNITY_HALF_TEXEL_OFFSET
o.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = i.color;
col.a *= tex2D(_MainTex, i.texcoord).a;
clip (col.a - 0.01);
return col;
}
ENDCG
}
}
}
↧
Answer by Julien-Lynge
The previous answers basically involve you copying Unity's built-in UI shader and then overriding the ZTest value. Unity actually built the UI shaders with ShaderLab named values, meaning you can solve this with just a line of code. That way, you can always use Unity's latest shaders without having to hard code anything.
Here's an example script that allows you to test the code in the editor. Just attach it to your Image and hit 'apply' in the inspector.
In a nutshell, I'm just making a copy of Unity's default rendering material, then changing the value of ZTest on the copy, then applying it back to the Image. This will work for any UI graphic - text, etc.
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode]
public class CustomRenderQueue : MonoBehaviour {
public UnityEngine.Rendering.CompareFunction comparison = UnityEngine.Rendering.CompareFunction.Always;
public bool apply = false;
private void Update()
{
if (apply)
{
apply = false;
Debug.Log("Updated material val");
Image image = GetComponent
();
Material existingGlobalMat = image.materialForRendering;
Material updatedMaterial = new Material(existingGlobalMat);
updatedMaterial.SetInt("unity_GUIZTestMode", (int)comparison);
image.material = updatedMaterial;
}
}
}
↧
Answer by glitchers
Based on Julien-Lynge 's answer I've created this script - https://gist.github.com/glitchersgames/5a9b5f256c1f160d92399749a4776d8d
---
It works in the same way of just overriding the Z Test but does it using the built-in Unity way for overriding UI materials, and it runs much less often so it should perform better.
---
In-line script (same as Gist):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Rendering;
namespace Glitchers.UserInterface
{
public class CustomZTestUI : MonoBehaviour, IMaterialModifier
{
#region Serialized
[Tooltip("LessEqual is 'normal'. Always is overlay. Never is hide.")]
public CompareFunction comparison = CompareFunction.LessEqual;
#endregion
#region Variables
private Graphic m_Graphic;
private Material m_RenderMaterial;
#endregion
#region Properties
private const string _propertyKey = "unity_GUIZTestMode";
private static int? _propertyID = null;
private static int PropertyID
{
get
{
if(_propertyID.HasValue==false)
{
_propertyID = Shader.PropertyToID(_propertyKey);
}
return _propertyID.Value;
}
}
#endregion
#region Lifecycle
private void Awake()
{
m_Graphic = GetComponent();
}
private void OnEnable()
{
SetDirty();
}
private void OnDisable()
{
SetDirty();
}
#if UNITY_EDITOR
private void OnValidate()
{
if(m_Graphic==null)
{
m_Graphic = GetComponent();
}
SetDirty();
}
#endif
#endregion
#region Methods
private void SetDirty()
{
if(m_Graphic!=null)
{
m_Graphic.SetMaterialDirty();
}
}
#endregion
#region IMaterialModifier
Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
{
#if UNITY_EDITOR
if( Application.isPlaying == false )
{
return baseMaterial;
}
#endif
if(m_RenderMaterial==null)
{
m_RenderMaterial = new Material(baseMaterial)
{
name = string.Format("{0} CustomZTestUI", baseMaterial.name),
hideFlags = HideFlags.HideAndDontSave
};
}
m_RenderMaterial.SetInt(PropertyID, (int)comparison);
return m_RenderMaterial;
}
#endregion
}
}
↧