Unity MeshRenderer 渲染排序问题(SortingLayer与order in layer的设置)

        Unity中我们需要区分Layer(LayerMask),SortingLayer,SortingOrder他们的区别。Layer是Unity中方便在Player设置碰撞检测(如下图),还有就是方便Camera挑选显示各个层级(UI层,特效层,Player,NPC等,如下图),最多只能设置32个。SortingLayer是控制渲染的层级的,SortingOrder是控制层级中显示的顺序,是属于SortingLayer的。

        3d项目中,如创建一个cube,在Inspector中并没有sorting layer和order in layer这两个字段。如果需要更改排序,我们可以通过直接通过脚本写入;也可以通过编写editor脚本将sorting layer和order in layer这两个字段在Inspector中显示出来,并进行设置。

public class MeshRenderEditor : Editor
{
    MeshRenderer meshRenderer;

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        meshRenderer = target as MeshRenderer;

        string[] layerNames = new string[SortingLayer.layers.Length];
        for (int i = 0; i < layerNames.Length; i++)
        {
            layerNames[i] = SortingLayer.layers[i].name;
        }

        int layerValue = SortingLayer.GetLayerValueFromID(meshRenderer.sortingLayerID);
        layerValue = EditorGUILayout.Popup("Sorting Layer", layerValue, layerNames);

        SortingLayer layer = SortingLayer.layers[layerValue];
        meshRenderer.sortingLayerName = layer.name;
        meshRenderer.sortingLayerID = layer.id;
        meshRenderer.sortingOrder = EditorGUILayout.IntField("Order In Value", meshRenderer.sortingOrder);
    }
}

修改SortingLayer的工具,获取所有的prefab,再获取prefab中的所有MeshRenderer,最后再修改MeshRenderer组件上的SortingLayer,SortingOrder(如下):

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class ModifySortOrder : EditorWindow
{
    private Dictionary<string, string> dicLayers = null;
    private static string searchPath = string.Empty;
    private string[] searchDir;

    [MenuItem("Tools/SortLayer")]
    public static void ShowSortLayer()
    {
        Rect rect = new Rect(0, 0, 300, 300);
        EditorWindow wondiw = EditorWindow.GetWindowWithRect(typeof(ModifySortOrder), rect, false, "SortLayer");
        wondiw.Show();
    }

    private void OnGUI()
    {
        if(dicLayers == null)
        {
            ReadTxt();
        }

        string str = EditorGUILayout.TextField("路径:", searchPath);
        int num = string.Compare(str, searchPath, true);
        if (num != 0)
        {
            searchPath = str;
        }

        searchDir = new string[] { "Assets" + searchPath };
        if (GUILayout.Button("查找Prefab"))
        {
            SearchPrefabs();
        }
    }

    private void SearchPrefabs()
    {
        string[] prefabPaths = AssetDatabase.FindAssets("t:Prefab", searchDir);

        for (int i = 0; i < prefabPaths.Length; i++)
        {
            EditorUtility.DisplayProgressBar("获取Prefab", i + "/" + prefabPaths.Length, i * 1.0f / prefabPaths.Length);
            string prefabPath = AssetDatabase.GUIDToAssetPath(prefabPaths[i]);
            GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
            if(obj != null)
            {
                GetPrefabMeshes(obj, prefabPaths.Length - i);
            }
        }

        AssetDatabase.SaveAssets();
        EditorUtility.ClearProgressBar();
    }

    private void GetPrefabMeshes(GameObject obj,int sortOrder)
    {
        MeshRenderer[] meshes = obj.GetComponentsInChildren<MeshRenderer>();
        for (int i= 0; i < meshes.Length; i++)
        {
            string shaderName = meshes[i].sharedMaterial.shader.name;
            string sortLayer = GetSortLayer(shaderName);

            meshes[i].sortingLayerName = sortLayer;
            meshes[i].sortingOrder = sortOrder;
            //meshes[i].sortingLayerName = "default";
            //meshes[i].sortingOrder = 0;
            //string format = string.Format("LayerName:{0},SortOrder:{1}", meshes[i].sortingLayerName, meshes[i].sortingOrder);
            //Debug.Log(format);
        }
    }

    /// <summary>
    /// 根据配置表,配置好shader的Layer和order
    /// </summary>
    /// <param name="shaderName"></param>
    private string GetSortLayer(string shaderName)
    {
        if (dicLayers.ContainsKey(shaderName))
        {
            return dicLayers[shaderName];
        }
        else
        {
            Debug.LogError("shaderName:" + shaderName + ".不存在配置表中");
        }

        return null;
    }

    private void ReadTxt()
    {
        dicLayers = new Dictionary<string, string>();
        string txtPath = Application.dataPath.Replace("Assets", "SortingLayer.txt");
        StreamReader stReader = new StreamReader(txtPath);
        while (!stReader.EndOfStream)
        {
            string line = stReader.ReadLine();
            if (!string.IsNullOrEmpty(line))
            {
                string[] layers = line.Split(',');
                if (dicLayers.ContainsKey(layers[1]))
                {
                    Debug.Log("配置表中有相同的shader命名");
                }
                else
                {
                    dicLayers.Add(layers[1], layers[0]);
                }
            }
        }
    }
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值