Hello Guys, As we know since Unity 4.3, Unity have a sort layer manager. This feature is exposed and fully manageable from Edit->Project Settings->Tags and Layers. Every Renderer have some exposed variables to deal with the sort layer but only the Sprite Renderer has it exposed on the inspector. So I find a way to do an extension to Unity Renderers, adding sort layer options as in Sprite Renderer to every Renderer. (so you can use it at TrailRenderer, LineRenderer, ParticleLegacyRenderer and etc...) I did it yesterday so I`m not sure, at this moment, if it really works as it should work in all cases. The code is also a little dirt (sorry for that). I also added a include child toggle option because well... it`s quite useful. I tried to do the same in Shuriken Particle System but I`m new in this Custom Editor thing and I`m not able to change Shuriken Particle System without destroy that charming look from Shuriken Particle System Inspector. Code (csharp): // SortLayerRendererExtension.cs // Author: // Yves J. Albuquerque <yves.albuquerque@gmail.com> // Last Update: // 27-12-2013 //Put this file into a folder named Editor. //Based on Nick`s code at https://gist.github.com/nickgravelyn/7460288 and Ivan Murashko solution at http://forum.unity3d.com/threads/210683-List-of-sorting-layers?p=1432958&viewfull=1#post1432958 aput by Guavaman at http://answers.unity3d.com/questions/585108/how-do-you-access-sorting-layers-via-scripting.html using System; using UnityEngine; using UnityEditor; using UnityEditorInternal; using System.Reflection; [CanEditMultipleObjects()] [CustomEditor(typeof(Renderer),true)] public class SortLayerRendererExtension : Editor { Renderer renderer; Renderer[] childsRenderer; string[] sortingLayerNames; int selectedOption; bool applyToChild = false; bool applyToChildOldValue = false; void OnEnable() { sortingLayerNames = GetSortingLayerNames(); renderer = (target as Renderer).gameObject.renderer; if ((target as Renderer).transform.childCount > 1) childsRenderer = (target as SortingLayerExposed).transform.GetComponentsInChildren<Renderer>(); for (int i = 0; i<sortingLayerNames.Length;i++) { if (sortingLayerNames[i] == renderer.sortingLayerName) selectedOption = i; } } public override void OnInspectorGUI() { DrawDefaultInspector(); if (!renderer) { return; } EditorGUILayout.LabelField("\n"); selectedOption = EditorGUILayout.Popup("Sorting Layer", selectedOption, sortingLayerNames); if (sortingLayerNames[selectedOption] != renderer.sortingLayerName) { Undo.RecordObject(renderer, "Sorting Layer"); if (!applyToChild) renderer.sortingLayerName = sortingLayerNames[selectedOption]; else { for (int i = 0; i<childsRenderer.Length;i++) { childsRenderer[i].sortingLayerName = sortingLayerNames[selectedOption]; } } EditorUtility.SetDirty(renderer); } int newSortingLayerOrder = EditorGUILayout.IntField("Order in Layer", renderer.sortingOrder); if (newSortingLayerOrder != renderer.sortingOrder) { Undo.RecordObject(renderer, "Edit Sorting Order"); renderer.sortingOrder = newSortingLayerOrder; EditorUtility.SetDirty(renderer); } applyToChild = EditorGUILayout.ToggleLeft("Apply to Childs", applyToChild); if (applyToChild != applyToChildOldValue) { for (int i = 0; i<childsRenderer.Length;i++) { childsRenderer[i].sortingLayerName = sortingLayerNames[selectedOption]; } Undo.RecordObject(renderer, "Apply Sort Mode To Child"); applyToChildOldValue = applyToChild; EditorUtility.SetDirty(renderer); } } // Get the sorting layer names public string[] GetSortingLayerNames() { Type internalEditorUtilityType = typeof(InternalEditorUtility); PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic); return (string[])sortingLayersProperty.GetValue(null, new object[0]); } // Get the unique sorting layer IDs -- tossed this in for good measure public int[] GetSortingLayerUniqueIDs() { Type internalEditorUtilityType = typeof(InternalEditorUtility); PropertyInfo sortingLayerUniqueIDsProperty = internalEditorUtilityType.GetProperty("sortingLayerUniqueIDs", BindingFlags.Static | BindingFlags.NonPublic); return (int[])sortingLayerUniqueIDsProperty.GetValue(null, new object[0]); } } EDIT: Still wanted some help here but I did a little trick. Not the wanted solution but worked until someone comes with an integrated solution for Shuriken. This is the Editor code Code (csharp): // RendererLayerEditor.cs // Author: // Yves J. Albuquerque <yves.albuquerque@gmail.com> // Last Update: // 28-12-2013 //Put this file into a folder named Editor. //Based on Nick`s code at https://gist.github.com/nickgravelyn/7460288 and Ivan Murashko solution at http://forum.unity3d.com/threads/210683-List-of-sorting-layers?p=1432958&viewfull=1#post1432958 aput by Guavaman at http://answers.unity3d.com/questions/585108/how-do-you-access-sorting-layers-via-scripting.html using System; using UnityEngine; using UnityEditor; using UnityEditorInternal; using System.Reflection; [CanEditMultipleObjects()] [CustomEditor(typeof(RendererLayer))] public class RendererLayerEditor : Editor { ParticleSystem[] l_particleSystems; //reference to our particle systems Renderer[] l_renderers;//reference to our renderers string[] sortingLayerNames;//we load here our Layer names to be displayed at the popup GUI int popupMenuIndex;//The selected GUI popup Index bool applyToChild = false;//Turn on/off if the effect will be extended to all renderers in child transforms bool applyToChildOldValue = false;//Used this old value to detect changes in applyToChild boolean /// <summary> /// Raises the enable event. We use it to set some references and do some initialization. I don`t figured out how to make a variable persistent in Unity Editor yet so most of the codes here can useless /// </summary> void OnEnable() { sortingLayerNames = GetSortingLayerNames(); //First we load the name of our layers l_particleSystems = (target as RendererLayer).gameObject.GetComponentsInChildren<ParticleSystem>();//Then we load our ParticleSystems l_renderers = new Renderer[l_particleSystems.Length];//and Initialize our renderers array with the right size for (int i = 0; i<l_particleSystems.Length;i++) //here we loads all renderers to our renderersarray { l_renderers[i] = l_particleSystems[i].renderer; } for (int i = 0; i<sortingLayerNames.Length;i++) //here we initialize our popupMenuIndex with the current Sort Layer Name { if (sortingLayerNames[i] == l_particleSystems[0].renderer.sortingLayerName) popupMenuIndex = i; } } /// <summary> /// OnInspectorGUI is where the magic happens. Here we draw and change all the stuff /// </summary> public override void OnInspectorGUI() { DrawDefaultInspector(); //first we draw our DefaultInspector if (l_renderers.Length == 0) //if there`s no Renderer at this object { return; //returns } popupMenuIndex = EditorGUILayout.Popup("Sorting Layer", popupMenuIndex, sortingLayerNames);//The popup menu is displayed simple as that int newSortingLayerOrder = EditorGUILayout.IntField("Order in Layer", l_renderers[0].sortingOrder); //Specifies the order to be drawed in this particular SortLayer applyToChild = EditorGUILayout.ToggleLeft("Apply to Childs", applyToChild);//If this change will be applyed to every renderer or just this one if (sortingLayerNames[popupMenuIndex] != l_renderers[0].sortingLayerName || newSortingLayerOrder != l_renderers[0].sortingOrder || applyToChild != applyToChildOldValue) //if there`s some change { Undo.RecordObject(l_renderers[0], "Change Particle System Renderer Order"); //first let record this change into Undo class so if the user did a mess, he can use ctrl+z to undo if (applyToChild) //change sortingLayerName and sortingOrder in each Renderer { for (int i = 0; i<l_renderers.Length;i++) { l_renderers[i].sortingLayerName = sortingLayerNames[popupMenuIndex]; l_renderers[i].sortingOrder = newSortingLayerOrder; } } else //or at least at this one { l_renderers[0].sortingLayerName = sortingLayerNames[popupMenuIndex]; l_renderers[0].sortingOrder = newSortingLayerOrder; } EditorUtility.SetDirty(l_renderers[0]); //saves } } // Get the sorting layer names public string[] GetSortingLayerNames() { Type internalEditorUtilityType = typeof(InternalEditorUtility); PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic); return (string[])sortingLayersProperty.GetValue(null, new object[0]); } } But unfortunately you need to put a code in your Shuriken Effect. An almost empty code with a particular name. Sad but true. Code (csharp): using UnityEngine; public class RendererLayer : MonoBehaviour{}
I'm not using Shuriken, but need help showing the sorting layer for non sprites. How exactly do I proceed with this?
I want to try this but it isn't working for me. The first script doesn't even compile, it says: .../ShortLayerRendererExtension.cs(77,77): Error CS0246: The type or namespace name `SortingLayerExposed' could not be found. Are you missing a using directive or an assembly reference? (CS0246) (Assembly-CSharp-Editor) Where is that class defined? Bests!
Ok, forget my previous question. I found the git repository here: https://gist.github.com/nickgravelyn/7460288
You might like to try this guy's free addon. It seems to be pretty slick, though the sorting orders seem to reset after a play / stop. https://www.assetstore.unity3d.com/en/#!/content/16505
Hello guys, I've included an updated version of Sort Layer Renderer at Asset Store. (Compatible with Unity 5) It's included into a tutorial called ESR (Now, for FREE). Best regards,