Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Drawing order of Meshes and Sprites

Discussion in '2D' started by Lexandritte, Nov 19, 2013.

  1. Lexandritte

    Lexandritte

    Joined:
    Nov 19, 2013
    Posts:
    1
    Hello, everyone.
    I'm asking the question on behalf of my brutal and unshaven programmer partner from Russia.

    In the new and shiny 4.3 version, Sprites can be given a rendering order in their layer. They also have something called Sorting Layers, which seems to relate to that as well.

    However, when the scene combines both Sprites and Meshes, meshes do not have anything relating to rendering order, at least nothing I can find.

    So, the question is, how can I place a mesh in rendering order relative to a sprite and vice versa?
     
    Last edited: Nov 19, 2013
    rakkarage likes this.
  2. neror

    neror

    Joined:
    Jul 25, 2011
    Posts:
    6
    I've been desperately searching for this as well. I can't get any mesh which uses a MeshRenderer to draw over SpriteRenderers with an orthographic camera. I've tried everything I can think of short of drawing the MeshRenderers with different cameras. I've played with the z-order, I've even messed with the renderQueues on the materials. Nothing will draw over a SpriteRenderer.

    I hope I'm just missing something.
     
    sean244 likes this.
  3. neror

    neror

    Joined:
    Jul 25, 2011
    Posts:
    6
    So I answered my own question with a search of the forum. I can't believe I struggled with this for days before finding this thread:

    http://forum.unity3d.com/threads/211822-Using-non-Sprites-with-the-new-sorting-layers

    If anyone's interested, I threw together a quick editor script to expose the sorting layers on the MeshRenderer component in the inspector. Unfortunately, I couldn't figure out how to find all of the layer names via script. So it's just a text field. Use with care.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6. [CustomEditor(typeof(MeshRenderer))]
    7. public class MeshRendererSortingLayersEditor : Editor
    8. {
    9.  
    10.     public override void OnInspectorGUI()
    11.     {
    12.         base.OnInspectorGUI();
    13.  
    14.         MeshRenderer renderer = target as MeshRenderer;
    15.  
    16.         EditorGUILayout.BeginHorizontal();
    17.         EditorGUI.BeginChangeCheck();
    18.         string name = EditorGUILayout.TextField("Sorting Layer Name", renderer.sortingLayerName);
    19.         if(EditorGUI.EndChangeCheck()) {
    20.             renderer.sortingLayerName = name;
    21.         }
    22.         EditorGUILayout.EndHorizontal();
    23.  
    24.         EditorGUILayout.BeginHorizontal();
    25.         EditorGUI.BeginChangeCheck();
    26.         int order = EditorGUILayout.IntField("Sorting Order", renderer.sortingOrder);
    27.         if(EditorGUI.EndChangeCheck()) {
    28.             renderer.sortingOrder = order;
    29.         }
    30.         EditorGUILayout.EndHorizontal();
    31.  
    32.     }
    33. }
    34.  
    35.  
     
  4. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    (please forgive me in advance for my bad english)
    Thx, man. this works! But if get "unlit/texture" shader, object will draw without this options (they use Z order). I think that not all shader programm working equally with sorting layers. But "sprites/default" shader works fine.
     
  5. trevex

    trevex

    Joined:
    Apr 10, 2013
    Posts:
    17
    Thanks!
    Ran into the same problem, works flawlessly for me.
     
  6. kellygravelyn

    kellygravelyn

    Joined:
    Jan 22, 2009
    Posts:
    143
    I was looking into this today and wanted to add some details to the thread for people in the future.

    When using rendering order you're setting the order in which Unity tells the GPU to draw the objects, nothing more. At that point it's up to the shaders/materials to define how the GPU draws the object on the screen.

    The sprite shaders all set "ZWrite Off" which tells the GPU not to write to the Z/depth buffer when drawing. This ensures a scene with nothing but sprites will have an empty Z/depth buffer and therefore every draw will put a sprite on screen.

    If you want to integrate 3D objects in the scene, they don't have to use the sprite shaders, but they also should set "ZWrite Off" so they also don't write to the depth buffer. This can have some interesting consequences with 3D meshes (particularly if a single mesh goes behind itself, like with a 3D character). But for cubes or other simple convex meshes, it works quite well.

    So the moral is: you don't have to use the sprite shaders, but you can't use the default mesh shaders because they all use the Z/depth buffer. Make a new shader (or copy one of the defaults) and set "ZWrite Off" and you'll be good to go with sorting layers.
     
  7. Dreikorn23

    Dreikorn23

    Joined:
    Apr 27, 2014
    Posts:
    1
    Thank you neror!! I was about to begin scripting shaders when I saw your reply.
    Good work!
     
  8. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Nice solution neror. I combined your solution with a script to get a list of sorting layer names, to display a nice drop down list similar to ones in SpriteRenderer so you don't have to type exact name. You can also have bold text on prefab override,undo and revert to prefab because I used the SerializedProperty.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. #if UNITY_EDITOR
    4. using UnityEditor;
    5. using UnityEditorInternal;
    6. using System.Reflection;
    7. using System;
    8. #endif
    9.  
    10. //Expose SortingLayer  SortingOrder on MeshRenderer
    11. //With nice drop down and revert to prefab functionality.
    12.  
    13. //Base exposing code by neror http://forum.unity3d.com/threads/212006-Drawing-order-of-Meshes-and-Sprites
    14. //Get all sorting layer name and ID by guavaman  Ivan.Murashko http://answers.unity3d.com/questions/585108/how-do-you-access-sorting-layers-via-scripting.html
    15. //Sorting Layer drop down menu, bold text on prefab override, revert to prefab and instant update on Order change functionality by 5argon
    16.  
    17. [CustomEditor(typeof(MeshRenderer))]
    18.  
    19. public class MeshRendererSortingLayersEditor : Editor
    20. {
    21.  
    22.     public override void OnInspectorGUI()
    23.     {
    24.  
    25.         base.OnInspectorGUI();
    26.  
    27.         serializedObject.Update();
    28.  
    29.         SerializedProperty sortingLayerID = serializedObject.FindProperty("m_SortingLayerID");
    30.         SerializedProperty sortingOrder = serializedObject.FindProperty("m_SortingOrder");
    31.  
    32.         MeshRenderer renderer = target as MeshRenderer;
    33.  
    34.         Rect firstHoriz = EditorGUILayout.BeginHorizontal();
    35.  
    36.         EditorGUI.BeginChangeCheck();
    37.  
    38.         EditorGUI.BeginProperty(firstHoriz,GUIContent.none,sortingLayerID);
    39.  
    40.         string[] layerNames = GetSortingLayerNames();
    41.         int[] layerID = GetSortingLayerUniqueIDs();
    42.  
    43.         int selected = -1;
    44.         //What is selected?
    45.         int sID = sortingLayerID.intValue;
    46.         for(int i = 0 ; i < layerID.Length ; i++)
    47.         {
    48.             //Debug.Log(sID + " " + layerID[i]);
    49.             if(sID == layerID[i])
    50.             {
    51.                 selected = i;
    52.             }
    53.         }
    54.  
    55.         if(selected == -1)
    56.         {
    57.             //Select Default.
    58.             for(int i = 0 ; i < layerID.Length ; i++)
    59.             {
    60.                 if(layerID[i] == 0)
    61.                 {
    62.                     selected = i;
    63.                 }
    64.             }
    65.         }
    66.  
    67.         selected = EditorGUILayout.Popup("Sorting Layer" ,selected,layerNames);
    68.  
    69.         //Translate to ID
    70.         sortingLayerID.intValue = layerID[selected];
    71.  
    72.  
    73.         EditorGUI.EndProperty();
    74.  
    75.         EditorGUILayout.EndHorizontal();
    76.  
    77.         EditorGUILayout.BeginHorizontal();
    78.         EditorGUI.BeginChangeCheck();
    79.  
    80.         EditorGUILayout.PropertyField(sortingOrder,new GUIContent("Order in Layer"));
    81.  
    82.  
    83.         EditorGUILayout.EndHorizontal();
    84.         serializedObject.ApplyModifiedProperties();
    85.     }
    86.  
    87.     public string[] GetSortingLayerNames() {
    88.         Type internalEditorUtilityType = typeof(InternalEditorUtility);
    89.         PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
    90.         return (string[])sortingLayersProperty.GetValue(null, new object[0]);
    91.     }
    92.  
    93.     public int[] GetSortingLayerUniqueIDs() {
    94.         Type internalEditorUtilityType = typeof(InternalEditorUtility);
    95.         PropertyInfo sortingLayerUniqueIDsProperty = internalEditorUtilityType.GetProperty("sortingLayerUniqueIDs", BindingFlags.Static | BindingFlags.NonPublic);
    96.         return (int[])sortingLayerUniqueIDsProperty.GetValue(null, new object[0]);
    97.     }
    98.  
    99. }
    100.  
     
    Last edited: May 28, 2014
  9. jimutt

    jimutt

    Joined:
    Aug 22, 2013
    Posts:
    4
    Thanks argon and neror! Works just great :)
     
  10. unmaxim

    unmaxim

    Joined:
    Jul 25, 2013
    Posts:
    6
    5argon, you forgot to add
    Code (CSharp):
    1. [CanEditMultipleObjects]
    on line 18, just after
    Code (CSharp):
    1. [CustomEditor(typeof(MeshRenderer))]
     
    Wheatsten_SK likes this.
  11. emmalloyd

    emmalloyd

    Joined:
    Dec 5, 2013
    Posts:
    20
    Thank you, that script seems to have just solved my problem also. :)
     
  12. RDeluxe

    RDeluxe

    Joined:
    Sep 29, 2013
    Posts:
    117
  13. karathepirate

    karathepirate

    Joined:
    Oct 9, 2013
    Posts:
    1
    Thanks, this solved a problem for me. Like mf_andreich said, I got it to work by setting the shader material to sprite-default. This works for particle systems too! Parent your particle system to an empty game object with a Mesh Renderer attached. Set the material on that empty game object to sprites-default and the particle system will display in the right sorting order too :) A bit of a work around....but we all love our particles
     
    theANMATOR2b likes this.
  14. RDeluxe

    RDeluxe

    Joined:
    Sep 29, 2013
    Posts:
    117
    Well, sadly I can't use this trick, like nickgravelyn said, it creates problem with complex 3D models (the texture "can't rotate")
     
  15. velipekka

    velipekka

    Joined:
    Jun 2, 2014
    Posts:
    9
    RDeluxe, can I ask you what kind of sorting problem you have with your scene?
    The sorting system should be pretty flexible, when you know all the tricks :D
     
  16. xCyborg

    xCyborg

    Joined:
    Oct 4, 2010
    Posts:
    632
    In Unity 5, sorting layer and order are exposed in the inspector for both the mesh renderer component and the particle system renderer. But the renderer still draws 3d meshes based on their z-position, maybe this will be fixed by the final release but I'm so thankful for this anyways.
     
    rakkarage likes this.
  17. glenwatkinson

    glenwatkinson

    Joined:
    Apr 13, 2013
    Posts:
    3
    Wrestling with a similar problem I found a different solution. I wanted a shader which plays nice with my sprite rendering layers but also allows me to mess with the texture's offset and tiling numbers. Neror's script worked great with the first part but unfortunately the Sprites/Default shader wouldn't allow me to change the numbers.

    Slightly different from what Nick Gravelyn said (although his post definitely sent me on the right track) I couldn't get this to work by including the "ZWrite Off" flag to a customized version of the Unlit-Normal shader. Rather I had to add the below tag:

    Tags
    {
    "Queue"="Transparent"
    }
     
  18. Ferb

    Ferb

    Joined:
    Jan 4, 2014
    Posts:
    25
    I had all this working fine in Unity 4.6 and below (using the advice in this thread - basically, meshes using custom shaders with ZWrite Off), but after upgrading to Unity 5 both the sorting layer and order of my meshes now seems to be being ignored (well, actually it's maintained most of the time, but if there is any pattern as to when the order is or isn't maintained, I have yet to discover it). Does anyone else have this problem, or know how to solve it?

    The sorting layers aren't so much a problem - the different layers are almost all using different shaders (and where they aren't I could make two identical shaders so each layer has its own copy), so I could set the rendering Queue tag differently in the different shaders to force the order to be correct. And I guess there's only one layer in which there's a bunch of meshes requiring a certain order, and I could soon rewrite it to be drawn using Z-buffering. So there's no emergency, it's just my solution is a bit inelegant - it makes it more difficult if I want to change the drawing order at some point. So it would still be nice if anyone knows how to get the real sorting order working again in Unity 5.
     
  19. Ferb

    Ferb

    Joined:
    Jan 4, 2014
    Posts:
    25
    Actually, none of my previously proposed workarounds work. Using Z-buffering for transparent sprites doesn't work because if the background has two layers, front and back, and only the back layer of the background has been drawn before the transparent sprite is drawn, then the transparent parts of the sprite end up showing the back layer of the background instead of the front layer.

    I have found the problem though, that the sorting layers were being set in code by their id, where the id was assumed to be a small integer (similar to the id used for a collision layer). I see now that the sorting layer id is a big hashcode, but the strange thing is that the small integers, which I based on the order in which I'd created new sorting layers, did work fine in Unity 4 (hence my only having a problem when I upgraded), even though it's undocumented. Anyway, I've switched to using the big hashcodes now, and everything is fine. To find out what the sorting layer IDs are, by the way, look at the table of sorting layers (under 'Tags and Layers' in Project Settings) while the editor is in Debug mode (one of the settings accessible from the drop-down menu at the top-right). Strangely, it displays the IDs as unsigned integers, but the SortingLayerID property will only take a signed integer, so some of the IDs you see in the editor may need 2^32 subtracting from them before you can use them.
     
    Last edited: Mar 26, 2015
  20. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    this was fixed in 5?
    mr.png
    i don't see it?
    thanks
     
  21. Ferb

    Ferb

    Joined:
    Jan 4, 2014
    Posts:
    25
    Well, it's not just you, I can tell you that much. I haven't seen that myself either. I'm guessing it just happened in some beta version, and perhaps was never intentional. What's worse is that the editor script above isn't working in Unity 5 - not for me, anyway, and I haven't managed to work out how to fix it, or even why it's stopped working. The best I could suggest for now, if you want it visible in the editor, is to write a little Monobehaviour with public properties for SortingOrder and SortingLayer, which assigns these properties to the MeshRenderer in its Awake function. Then you can add that script to anything that needs them setting, and they'll be visible in the editor via the public properties.
     
    rakkarage likes this.
  22. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683


    actually it works for me with this code i got here, but the reflection probe and anchor override are rendered differently?

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4. using UnityEditorInternal;
    5. using System.Reflection;
    6. using System;
    7. [CanEditMultipleObjects]
    8. [CustomEditor(typeof(MeshRenderer))]
    9. public class MeshRendererEditor : Editor
    10. {
    11.     public override void OnInspectorGUI()
    12.     {
    13.         base.OnInspectorGUI();
    14.         serializedObject.Update();
    15.         SerializedProperty sortingLayerID = serializedObject.FindProperty("m_SortingLayerID");
    16.         SerializedProperty sortingOrder = serializedObject.FindProperty("m_SortingOrder");
    17.         //MeshRenderer renderer = target as MeshRenderer;
    18.         Rect firstHoriz = EditorGUILayout.BeginHorizontal();
    19.         EditorGUI.BeginChangeCheck();
    20.         EditorGUI.BeginProperty(firstHoriz, GUIContent.none, sortingLayerID);
    21.         string[] layerNames = GetSortingLayerNames();
    22.         int[] layerID = GetSortingLayerUniqueIDs();
    23.         int selected = -1;
    24.         int sID = sortingLayerID.intValue;
    25.         for (int i = 0; i < layerID.Length; i++)
    26.             if (sID == layerID[i])
    27.                 selected = i;
    28.         if (selected == -1)
    29.             for (int i = 0; i < layerID.Length; i++)
    30.                 if (layerID[i] == 0)
    31.                     selected = i;
    32.         selected = EditorGUILayout.Popup("Sorting Layer", selected, layerNames);
    33.         sortingLayerID.intValue = layerID[selected];
    34.         EditorGUI.EndProperty();
    35.         EditorGUILayout.EndHorizontal();
    36.         EditorGUILayout.BeginHorizontal();
    37.         EditorGUI.BeginChangeCheck();
    38.         EditorGUILayout.PropertyField(sortingOrder, new GUIContent("Order in Layer"));
    39.         EditorGUILayout.EndHorizontal();
    40.         serializedObject.ApplyModifiedProperties();
    41.     }
    42.     public string[] GetSortingLayerNames()
    43.     {
    44.         Type internalEditorUtilityType = typeof(InternalEditorUtility);
    45.         PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
    46.         return (string[])sortingLayersProperty.GetValue(null, new object[0]);
    47.     }
    48.     public int[] GetSortingLayerUniqueIDs()
    49.     {
    50.         Type internalEditorUtilityType = typeof(InternalEditorUtility);
    51.         PropertyInfo sortingLayerUniqueIDsProperty = internalEditorUtilityType.GetProperty("sortingLayerUniqueIDs", BindingFlags.Static | BindingFlags.NonPublic);
    52.         return (int[])sortingLayerUniqueIDsProperty.GetValue(null, new object[0]);
    53.     }
    54. }
    55.  
     
    racSG likes this.
  23. noamgat

    noamgat

    Joined:
    Nov 22, 2009
    Posts:
    125
    I'm also getting the same side effect, as you guys. But it does do its job and affect the rendering order.
     
  24. xCyborg

    xCyborg

    Joined:
    Oct 4, 2010
    Posts:
    632
    Unfortunately they removed the last three parameters from the Mesh Renderer component, Why Unity Why?
     
  25. xCyborg

    xCyborg

    Joined:
    Oct 4, 2010
    Posts:
    632
    It was in early beta Alas,but atleast it's still there in Particle renderer.
     
  26. Kasc

    Kasc

    Joined:
    May 24, 2015
    Posts:
    1
    What's the status of this in the most up to date release of Unity? Is it possible to position meshes on a sprite drawing layer?
     
  27. GiyomuGames

    GiyomuGames

    Joined:
    Jan 12, 2015
    Posts:
    80
    Hi there,

    Same question as Kasc. I can't seem to be able to set the sorting layers to my mesh renderers in Unity 5.1. Anyone knows how to do it?
     
  28. tanoshimi

    tanoshimi

    Joined:
    May 21, 2013
    Posts:
    297
    As @nickgravelyn pointed out some time ago, the problem is caused by the fact that, generally, shaders on 3d meshes write to (and cull based on) the depth buffer, while shaders used to draw 2d sprites do not.

    But, rather than all these workarounds to try to add sorting layers to 3d meshes, why not change your sprite shader so that it does write to the Z buffer? In other words, just create a copy of the inbuilt Sprites-Default and add the ZWrite On subshader tag? Seems to work for me...
     
  29. GiyomuGames

    GiyomuGames

    Joined:
    Jan 12, 2015
    Posts:
    80
    Hi Tanoshimi,

    My problem is that I am using lighting and my Z-positions is ensuring that the lighting looks good, but doesn't ensure the order of the layer (i.e.: one sprite can be farther than another on Z for lighting purposes, but I want it to appear in front). So I can put Zwrite On but then some sprites are behind other sprites when it should be the other way around.

    I am curious to know if there is a way to tell the shader that we want to use the sortinglayers.
    Also, Zwrite off definitely works on SpriteRenderer but not on MeshRenderer, so could there be a way to make the MeshRenderer behave like a SpriteRenderer?
     
  30. RemDust

    RemDust

    Joined:
    Aug 28, 2015
    Posts:
    431
    Thank you so much for this code but I'm having an issue with it :
    it runs really great in the Editor but can't Build it because of compiles errors"VideoRenderer.cs(4,7): error CS0246: The type or namespace name `UnityEditorInternal' could not be found. Are you missing a using directive or an assembly reference?"

    I know this is an old thread now but if anyone has a suggestion it would be really appreciated !
     
  31. jc-drile77

    jc-drile77

    Joined:
    Jul 1, 2014
    Posts:
    230
    Hey, easy solution, you dont want that script on your build, do you?
    Just add :
    #if UNITY_EDITOR_64
    at the very beginning of the script and
    #endif
    at the end
     
    racSG and RemDust like this.
  32. RemDust

    RemDust

    Joined:
    Aug 28, 2015
    Posts:
    431
    But do I want the script to be skipped ?
    I mean the whole point is to have my clips rendered in the right order, so if the script is ignored, will my clips still be rendered in the desired order ? ^^
     
  33. jc-drile77

    jc-drile77

    Joined:
    Jul 1, 2014
    Posts:
    230
    The order is changed, that script is just an extension that allows us to change the sorting layer order,go ahead and try it your self with the two lines I said. You will see the result and thats unquestionable :)
    It´s like saying to Unity to show those options, once they are changed they remain changed even if they were hidden.
    Idk if I answered your question, if not please dont hesitate in asking again :D

    kind regards,
    jc-drile77

    Edit:
    The type or namespace name `UnityEditorInternal'...
    That line says it all, the error say: Hey! we are trying to make this code run but we need Unity´s editor and we are not building for it, where is it?... As I said above, it´s just a unity window extension :)
     
    Last edited: Jan 22, 2016
    theANMATOR2b and RemDust like this.
  34. Almakos

    Almakos

    Joined:
    Dec 13, 2013
    Posts:
    179
    Hey @jc-drile77
    I have placed your script in the Editor folder in my project, but I don't see any sorting layer field in my mesh renderer...
    in both normal and debug inspector modes.
    Am I doing something wrong?
    Thank you
     
  35. jc-drile77

    jc-drile77

    Joined:
    Jul 1, 2014
    Posts:
    230
    My bad, posted wrong one, any way, check this:
    https://github.com/nickgravelyn/UnityToolbag/tree/master/SortingLayer
    Doesnt have the other problem and works flawlessly.
    Or use this:
     
    Last edited: Jun 15, 2016
    seannam1218 and Almakos like this.
  36. unityBerserker

    unityBerserker

    Joined:
    Mar 31, 2016
    Posts:
    5
    Hi, I improved upper script to display mesh renderer component in normal way not like in debug mode.
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEditor;
    4. using UnityEditorInternal;
    5. using System.Reflection;
    6. using UnityEngine.Rendering;
    7.  
    8. [CanEditMultipleObjects ()]
    9. [CustomEditor (typeof(MeshRenderer))]
    10. public class MeshRendererSortingLayersEditor : Editor
    11. {
    12.    
    13.     public override void OnInspectorGUI ()
    14.     {
    15.  
    16.         #region Get Serialized Property
    17.         SerializedProperty sortingLayerID = serializedObject.FindProperty (propertyPath: "m_SortingLayerID");
    18.         SerializedProperty sortingOrder = serializedObject.FindProperty ("m_SortingOrder");
    19.  
    20.         SerializedProperty castShadows = serializedObject.FindProperty ("m_CastShadows");
    21.         SerializedProperty receiveShadows = serializedObject.FindProperty ("m_ReceiveShadows");
    22.         SerializedProperty motionVectors = serializedObject.FindProperty ("m_MotionVectors");
    23.         SerializedProperty materials = serializedObject.FindProperty ("m_Materials");
    24.         SerializedProperty lightProbes = serializedObject.FindProperty ("m_LightProbeUsage");
    25.         SerializedProperty reflectionProbes = serializedObject.FindProperty ("m_ReflectionProbeUsage");
    26.         SerializedProperty anchorProbes = serializedObject.FindProperty ("m_ProbeAnchor");
    27.         #endregion
    28.  
    29.         #region Draw Properties
    30.         AddPropertyField (castShadows);
    31.         AddPropertyField (receiveShadows);
    32.         AddPropertyField (motionVectors);
    33.         AddPropertyField (materials);
    34.         AddPopup (ref lightProbes, "Light Probes", typeof(LightProbeUsage));
    35.         AddPopup (ref reflectionProbes, "Reflection Probes", typeof(ReflectionProbeUsage));
    36.         AddPropertyField (anchorProbes, "Anchor Override");
    37.         #endregion
    38.    
    39.  
    40.         GUIStyle style = new GUIStyle (GUI.skin.label);
    41.         style.richText = true;
    42.         EditorGUILayout.Space ();
    43.         EditorGUILayout.LabelField ("<b><color=#EE4035FF>SortingLayers Options:</color></b>", style);
    44.         #region SortingLayer
    45.         Rect firstHoriz = EditorGUILayout.BeginHorizontal ();
    46.         EditorGUI.BeginChangeCheck ();
    47.         //    EditorGUI.PropertyField (mat, new GUIContent ("Materials"));
    48.         EditorGUI.BeginProperty (firstHoriz, GUIContent.none, sortingLayerID);
    49.         string[] layerNames = GetSortingLayerNames ();
    50.         int[] layerID = GetSortingLayerUniqueIDs ();
    51.         int selected = -1;
    52.         int sID = sortingLayerID.intValue;
    53.         for (int i = 0; i < layerID.Length; i++)
    54.             if (sID == layerID [i])
    55.                 selected = i;
    56.         if (selected == -1)
    57.             for (int i = 0; i < layerID.Length; i++)
    58.                 if (layerID [i] == 0)
    59.                     selected = i;
    60.         selected = EditorGUILayout.Popup ("Sorting Layer", selected, layerNames);
    61.  
    62.         sortingLayerID.intValue = layerID [selected];
    63.         EditorGUI.EndProperty ();
    64.         EditorGUILayout.EndHorizontal ();
    65.         #endregion
    66.  
    67.         #region OrderInLayer
    68.         EditorGUILayout.BeginHorizontal ();
    69.         EditorGUI.BeginChangeCheck ();
    70.         EditorGUILayout.PropertyField (sortingOrder, new GUIContent ("Order in Layer"));
    71.         EditorGUILayout.EndHorizontal ();
    72.         serializedObject.ApplyModifiedProperties ();
    73.         #endregion
    74.    
    75.  
    76.     }
    77.  
    78.     void AddPropertyField (SerializedProperty ourSerializedProperty)
    79.     {
    80.         Rect ourRect = EditorGUILayout.BeginHorizontal ();
    81.         EditorGUI.BeginProperty (ourRect, GUIContent.none, ourSerializedProperty);
    82.         EditorGUI.BeginChangeCheck ();
    83.  
    84.         EditorGUILayout.PropertyField (property: ourSerializedProperty, includeChildren: true); //I set includeChildren:true to display material children
    85.  
    86.         EditorGUI.EndProperty ();
    87.         EditorGUILayout.EndHorizontal ();
    88.     }
    89.  
    90.     void AddPropertyField (SerializedProperty ourSerializedProperty, string name)
    91.     {
    92.         Rect ourRect = EditorGUILayout.BeginHorizontal ();
    93.         EditorGUI.BeginProperty (ourRect, GUIContent.none, ourSerializedProperty);
    94.         EditorGUI.BeginChangeCheck ();
    95.  
    96.         EditorGUILayout.PropertyField (ourSerializedProperty, new GUIContent (name), true);
    97.  
    98.         EditorGUI.EndProperty ();
    99.         EditorGUILayout.EndHorizontal ();
    100.     }
    101.  
    102.     void AddPopup (ref SerializedProperty ourSerializedProperty, string nameOfLabel, Type typeOfEnum)
    103.     {
    104.         Rect ourRect = EditorGUILayout.BeginHorizontal ();
    105.         EditorGUI.BeginProperty (ourRect, GUIContent.none, ourSerializedProperty);
    106.         EditorGUI.BeginChangeCheck ();
    107.  
    108.         int actualSelected = 1;  
    109.         int selectionFromInspector = ourSerializedProperty.intValue;
    110.         string[] enumNamesList = System.Enum.GetNames (typeOfEnum);
    111.         actualSelected = EditorGUILayout.Popup (nameOfLabel, selectionFromInspector, enumNamesList);
    112.         ourSerializedProperty.intValue = actualSelected;
    113.    
    114.         EditorGUI.EndProperty ();
    115.         EditorGUILayout.EndHorizontal ();
    116.     }
    117.  
    118.  
    119.     public string[] GetSortingLayerNames ()
    120.     {
    121.         Type internalEditorUtilityType = typeof(InternalEditorUtility);
    122.         PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty ("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
    123.         return (string[])sortingLayersProperty.GetValue (null, new object[0]);
    124.     }
    125.  
    126.     public int[] GetSortingLayerUniqueIDs ()
    127.     {
    128.         Type internalEditorUtilityType = typeof(InternalEditorUtility);
    129.         PropertyInfo sortingLayerUniqueIDsProperty = internalEditorUtilityType.GetProperty ("sortingLayerUniqueIDs", BindingFlags.Static | BindingFlags.NonPublic);
    130.         return (int[])sortingLayerUniqueIDsProperty.GetValue (null, new object[0]);
    131.     }
    132. }
     
    Omer_Behar and aditya007 like this.
  37. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Hey,
    A quick fix that should work is just use a dedicated camera.
     
  38. xCyborg

    xCyborg

    Joined:
    Oct 4, 2010
    Posts:
    632
  39. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Why not try another camera?
     
  40. xCyborg

    xCyborg

    Joined:
    Oct 4, 2010
    Posts:
    632
    How is that? could you please elaborate on your workaround?
    But anyways this should be marked as a bug and we need a fix for it.
     
  41. AlanGreyjoy

    AlanGreyjoy

    Joined:
    Jul 25, 2014
    Posts:
    192
    4 years later... and this is still an issue?

    That's pretty damn impressive.....
     
    Miscellaneous and theANMATOR2b like this.
  42. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697


    I was setting up my UI, using Unity UI. I noticed that (not sure if related to Unity UI or not), that Sprite Renderers were drawn on top of Cube Meshes. So, as a solution, I dedicated a camera (same position, same angle, same size (zoom), just set a lower rank so that I can determine the sprite is drawn underneath.
     
  43. unityBerserker

    unityBerserker

    Joined:
    Mar 31, 2016
    Posts:
    5
    Sorting Layers work only with chosen shaders.
    It's for transparent objects like sprites.

    Opaque objects are renderered front to back so we use Z- buffer to check to render something.

    Transparent objects are rendered back to front. We don't use z- buffer. With must find way to sort them - that' s why we have sorting layers.

    Here you can find Build in Shaders:

    https://unity3d.com/get-unity/download/archive

    Download them.

    Copy Shandard shader and Sprites-Default shader and check their settings.

    In image you can see important setting.
    ZWrite must be set to off. Then you can use it with sorting layers.

    Simple test.
    Change Standard Shader copy as in image and check how it work with sorting layers.
    Or use Sprites-Default in MeshRenderer component.
     

    Attached Files:

  44. stuepfnick

    stuepfnick

    Joined:
    Apr 19, 2017
    Posts:
    18
    Phew - I did not read the complete thread now, because much seems to have changed.

    I have the exact opposite problem: I want player chat bubbles (sprites with text mesh on it) to draw above every 3D object, but sadly it does not do that.

    For the sprite and text mesh, relative to each other, it does work - for the MeshRender Component of the TextMesh, I could set the sortingOrder either with a text-editor in the Prefab or in runtime via code, to i.e. 1.

    But for the Sprite it does not help! I tried to set the SpriteRenderer to sortingOrder 1, and the Text to sortingOrder 2 - for the Text everything is fine and it draws over all 3D objects.

    But the bubble can easily get behind 3D objects. It does not seem to help, to set any sorting layers or sorting order, no idea why.

    I also tried to add a new Sorting Layer above Default and set the Text Bubbles to this layer with sorting 0 (sprite) and 1 (text).

    but nothing seems to help. So I can not see, that it will help to lower the sortingLayer or sortingOrder of the 3D objects, because they do not seem to be effected. (only if it is connected to a TextMesh)

    The SpriteRenderer will accept it's order relative to the MeshRenderer of the TextMesh. And gladly all the TextMeshes draw above the 3D scene, but not so for the SpriteRenderer.

    Even if I set the SpriteRenderer to be in front of the Text, it appears in front of the text, but the sprite itself is still behind 3D-objects (depending on z-buffer of course).

    So if I set it that way and the TextBubble disappears behind a 3D-object, it gets weird: The bubble wanders behind the 3D object, so it also does not cover the TextMesh anymore and the text gets freely visible, see screenshot:


    What can I do? Please help!
     
    Last edited: May 1, 2017
  45. GiyomuGames

    GiyomuGames

    Joined:
    Jan 12, 2015
    Posts:
    80
  46. stuepfnick

    stuepfnick

    Joined:
    Apr 19, 2017
    Posts:
    18
    Hm, that sound bit like overkill, also I don't know how to draw both cameras on each other. So I have to hook the same scripts, etc. to a second camera, so it works the same, just to change rendering order?

    Isn't there a more simple way to force the sprites to render in the foreground?

    PS: I could set position and orientation to the same objects for both cameras, like this:

    cam2.position = MainCamera.position
    cam2.orientation = MainCamera.orientation

    This way it should theoretically follow all the movement of the Main Camera. But how can I set the MainCamera to only render the 3d-stuff and the other one for Text and Sprites only?

    Also the TextMeshes already automatically appear on top of everything else, I just can't get the sprites to render on top of the other stuff.
     
    Last edited: May 2, 2017
  47. GiyomuGames

    GiyomuGames

    Joined:
    Jan 12, 2015
    Posts:
    80
    You could child the 2nd camera to the 1st one so they move together.

    Otherwise 1 thing you should check is the render queue of the materials you use for your 3D objects and for the sprites. If you use the default material for the sprites, then try creating a new material, set it to the default sprite shader and change the render queue if it is the same as the render queue of the material(s) you use for the 3D objects.
    Objects with a material with a higher render queue will be rendered later and will appear to be on top of the ones with a lower render queue.

    Another technique woud be to put your sprites closer to the camera to make sure they are always in front of the 3D objects (it may not be feasible depending on your game).
     
    Last edited: May 2, 2017
  48. stuepfnick

    stuepfnick

    Joined:
    Apr 19, 2017
    Posts:
    18
    Hi, thank you for the hints GyomuGames. I have no idea, ho to setup the cameras, so that one renders everything except text & sprites and to set the other to only render text and sprites.

    But the thing with the material sounds interesting. I will dig into how to set that up correctly.

    To put the sprites nearer to the camera is not really a practical option. Later on we might use an orthographic camera, but better to stay flexible. And it would have to be done different with perspective (move nearer but scale down) and ortho (move nearer, don't scale) cameras.

    Also the way with the materials sound better to implement (no extra calculations needed).
     
  49. GiyomuGames

    GiyomuGames

    Joined:
    Jan 12, 2015
    Posts:
    80
    No worries! Let us know how it turns out :)
     
  50. jc-drile77

    jc-drile77

    Joined:
    Jul 1, 2014
    Posts:
    230
    This is the one I use.(https://github.com/nickgravelyn/UnityToolbag/tree/master/SortingLayer)
    I believe it still works fine.
    Give it a try! :)