- Home /
How do you get a list of Sorting Layers via scripting?
Unity just added sorting layers in 4.3, however I cannot find where to access these layers via scripting in the docs. I know how to get a list of regular layers:
string[] options = new string[32];
for(int i = 0; i < 32; i++) { // get layer names
options[i] = i + " : " + LayerMask.LayerToName(i);
}
But I can't find anything else in the docs called layer, sorting layer, or anything related.
Answer by guavaman · Nov 27, 2013 at 10:45 PM
Thanks to Ivan.Murashko for answering this question yesterday on the forum.
C# version:
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Reflection;
public class SomeClass {
// 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]);
}
}
JS version:
#pragma strict
import UnityEditor;
import UnityEditorInternal;
import System.Reflection;
public class SomeClass {
// Get the sorting layer names
public function GetSortingLayerNames() : String[] {
var internalEditorUtilityType : System.Type = InternalEditorUtility;
var sortingLayersProperty : PropertyInfo = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
return sortingLayersProperty.GetValue(null, new System.Object[0]);
}
// Get the unique sorting layer IDs -- tossed this in for good measure
public function GetSortingLayerUniqueIDs() : int[] {
var internalEditorUtilityType : System.Type = InternalEditorUtility;
var sortingLayerUniqueIDsProperty : PropertyInfo = internalEditorUtilityType.GetProperty("sortingLayerUniqueIDs", BindingFlags.Static | BindingFlags.NonPublic);
return sortingLayerUniqueIDsProperty.GetValue(null, new System.Object[0]);
}
}
I tried to use your script. The names are properly retrived, but the unique ids give me incoherent numbers. What should be, for example, an id of 10 on the layer editor give me back -11475652 or the like in my script with GetSortingLayerUniqueIDs(). Any idea?
@Spidyy Those "incoherent" numbers are correct. These are unique ids internal to unity similar to a GUID so that no matter how you change the ordering of layers, an object that already has a layer assigned always stay assigned to the same layer. To set an object to this layer, assign the unique id to Renderer.m_SortingLayerID, which you will have to do via SerializedProperty.
If all you want to know is the current layer order, the name array is sorted by index as you see them in the inspector.
@Spidyy: To set an object to this layer, assign the unique id to Renderer.m_SortingLayerID, which you will have to do via SerializedProperty.
Can you post the code to do this? I don't know how to do it.
Answer by Sarkahn · Aug 22, 2016 at 06:37 PM
Not sure if this is new but as of 5.4 there is an easier way using the SortingLayer class which requires no reflection. Put this in an editor script and you can use it to draw a nice popup list similar to the one in SpriteRenderers.
/// /// Draws a popup of the project's existing sorting layers. /// </summary> /// <param name="layerID">The internal layer id, can be assigned to renderer.SortingLayerID to change sorting layers.</param> public static int DrawSortingLayersPopup( int layerID ) { var layers = SortingLayer.layers; var names = layers.Select(l => l.name).ToArray(); if( !SortingLayer.IsValid(layerID) ) { layerID = layers[0].id; } var layerValue = SortingLayer.GetLayerValueFromID(layerID); var newLayerValue = EditorGUILayout.Popup(layerValue, names); return layers[newLayerValue].id; }
Just make sure you're aware of the values you're getting from SortingLayer. "ID" means the internal unity value, "Value" means the actual index in the list of layers.
This will run into problems if you have a SortingLayer with negative value. I suggest replacing var layerValue = SortingLayer.GetLayerValueFromID(layerID); var newLayerValue = EditorGUILayout.Popup(layerValue, names);
with something like var entryIndex = Array.FindIndex(layers, l => l.id == layerID); var newLayerValue = EditorGUILayout.Popup(entryIndex, names);
to find the correct index in the list of layer names. (assu$$anonymous$$g "using System", a simple for-loop to find the index works just fine, of course)