Search code examples
c#unity-game-engineunity-editor

How to add sorting layer via script


I'm trying add sorting layer via script.

Can I add sorting layer via script? And how?


Solution

  • After some tests, i find the way.

    To adding sorting layer we need access to it's container.

    Sorting Layer is part of the TagManager.asset Object. (at reletive path on ProjectSettings directory.)

    This code can get TagManager as SerializedObject to modify it.

    var serializedObject = new SerializedObject(AssetDatabase.LoadMainAssetAtPath("ProjectSettings/TagManager.asset"));
    

    To get SortingLayer array we must Use below code:

    var sortingLayers = serializedObject.FindProperty("m_SortingLayers");
    

    We first check that our target SortingLayer does not exist in the array.

    var layerName = "SomeLayer";
    
    for (int i = 0; i < sortingLayers.arraySize; i++)
    {
        if (sortingLayers.GetArrayElementAtIndex(i).FindPropertyRelative("name").stringValue.Equals(layerName))
            return; // this mean target sorting layer exist and we don't need to add it.
    }
    

    Now add it if does not exist :

    sortingLayers.InsertArrayElementAtIndex(sortingLayers.arraySize);
    var newLayer = sortingLayers.GetArrayElementAtIndex(sortingLayers.arraySize - 1);
    newLayer.FindPropertyRelative("name").stringValue = layerName;
    newLayer.FindPropertyRelative("uniqueID").intValue = layerName.GetHashCode(); /* some unique number */
    

    Don't forget to apply to source:

    serializedObject.ApplyModifiedProperties();
    

    All of top code can compress to bellow method:

    public static void CreateSortingLayer(string layerName)
    {
        var serializedObject = new SerializedObject(AssetDatabase.LoadMainAssetAtPath("ProjectSettings/TagManager.asset"));
        var sortingLayers = serializedObject.FindProperty("m_SortingLayers");
        for (int i = 0; i < sortingLayers.arraySize; i++)
            if (sortingLayers.GetArrayElementAtIndex(i).FindPropertyRelative("name").stringValue.Equals(layerName))
                return;
        sortingLayers.InsertArrayElementAtIndex(sortingLayers.arraySize);
        var newLayer = sortingLayers.GetArrayElementAtIndex(sortingLayers.arraySize - 1);
        newLayer.FindPropertyRelative("name").stringValue = layerName;
        newLayer.FindPropertyRelative("uniqueID").intValue = layerName.GetHashCode(); /* some unique number */
        serializedObject.ApplyModifiedProperties();
    }