Combate de desarrollo del editor de Unity [MenuItem]: elimine por lotes el grupo LOD en la escena, retenga el nivel más alto de detalles

Si la escena contiene una gran cantidad de componentes del grupo LOD y no queremos usarlos, llevará mucho tiempo eliminarlos manualmente uno por uno.Este artículo presenta cómo escribir una herramienta que elimine los componentes del grupo LOD en la escena por lotes y solo conserva los objetos con el mayor nivel de detalle.

Ideas de implementación:

1. Use MenuItem para hacer un menú de funciones;

2. Al llamar a la función, una ventana emergente le recordará que confirme la eliminación del componente LOD Group en la escena;

3. Si el objeto pertenece a Prefab, la operación de destrucción no se puede realizar, por lo que es necesario confirmar si se realiza Prefab Unpack;

4. Atraviese todos los componentes del grupo LOD en la escena;

5. Atraviese la matriz de estructura LOD en el grupo LOD;

6. Atraviese el componente Renderer en cada estructura LOD y destruya el objeto donde se encuentra;

7. El componente del grupo LOD se destruye después del recorrido.

el código se muestra a continuación:

using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;

namespace SK.Framework
{
    /// <summary>
    /// LOD工具
    /// </summary>
    public class LODTool : Editor
    {
        [MenuItem("SKFramework/Tools/LOD/Delete")]
        private static void Open()
        {
            //弹出进行删除操作的提醒窗口
            bool confirm = EditorUtility.DisplayDialog("提醒", "是否确定删除场景中所有的LOD Group组件,只保留最高层次的细节", "确定", "取消");
            //点击取消则return
            if (!confirm) return;
            //弹出窗口 询问是否执行Prefab Unpack操作
            bool unpackPrefab = EditorUtility.DisplayDialog("确认", "如果目标物体属于Prefab预制体,执行Prefab Unpack操作还是跳过它?", "Unpack", "Skip");
            //获取当前场景中的所有根物体
            GameObject[] rootObjs = SceneManager.GetActiveScene().GetRootGameObjects();
            //遍历所有根物体
            for (int i = 0; i < rootObjs.Length; i++)
            {
                GameObject rootObj = rootObjs[i];
                //在根物体及子物体身上查找所有LOD Group组件
                LODGroup[] groups = rootObj.GetComponentsInChildren<LODGroup>(true);
                //遍历所有LOD Group组件
                for (int j = 0; j < groups.Length; j++)
                {
                    LODGroup group = groups[j];
                    GameObject obj = group.gameObject;
                    //获取LOD Group中的所有LOD结构
                    LOD[] lods = group.GetLODs();
                    if (lods.Length < 2) continue;
                    //遍历LOD结构 索引从1开始 保留最高层次的细节
                    for (int l = 1; l < lods.Length; l++)
                    {
                        LOD lod = lods[l];
                        //遍历LOD中的Renderer组件
                        for (int n = 0; n < lod.renderers.Length; n++)
                        {
                            Renderer renderer = lod.renderers[n];
                            if (renderer == null) continue;
                            //如果Renderer组件不为空 获取其挂载的物体
                            GameObject target = renderer.gameObject;
                            //物体不为空,进行销毁
                            if (target != null)
                            {
                                //如果目标物体属于Prefab预制体
                                if (PrefabUtility.IsPartOfAnyPrefab(target))
                                {
                                    if (unpackPrefab)
                                    {
                                        //获取Prefab预制体根级
                                        var prefabRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(target);
                                        //Prefab Unpack Completely
                                        PrefabUtility.UnpackPrefabInstance(prefabRoot, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
                                    }
                                    else continue;
                                }
                                //弹出进度条
                                EditorUtility.DisplayProgressBar("LOD deleting...", $"{rootObj.name}/{obj.name}/{target.name}", (i + 1) / rootObjs.Length);
                                DestroyImmediate(target);
                            }
                        }
                    }
                    Debug.Log($"删除{group.name}的LOD Group组件.");
                    //删除LOD Group组件
                    DestroyImmediate(group);
                    EditorUtility.SetDirty(obj);
                }
            }
            //清除进度条
            EditorUtility.ClearProgressBar();
        }
    }
}

 

   Bienvenidos a la cuenta pública "Programador Salvaje Contemporáneo"

Supongo que te gusta

Origin blog.csdn.net/qq_42139931/article/details/123637965
Recomendado
Clasificación