您当前的位置: 首页 >  unity

CoderZ1010

暂无认证

  • 6浏览

    0关注

    168博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Unity 编辑器开发实战【MenuItem】- 批量删除场景中的LOD Group,保留最高层次细节

CoderZ1010 发布时间:2022-03-21 16:19:26 ,浏览量:6

如果场景中包含大量的LOD Group组件,我们不想要使用时,手动依次删除需要耗费大量时间,本文介绍如何编写一个批量删除场景中LOD Group组件,并且只保留最高层次细节的物体的工具。

实现思路:

1.使用MenuItem制作一个功能菜单;

2.调用功能时,弹出窗口提醒确认删除场景中的LOD Group组件;

3.如果物体属于Prefab,不能进行销毁操作,因此还要确认是否进行Prefab Unpack;

4.遍历场景中的所有LOD Group组件;

5.遍历LOD Group中的LOD结构数组;

6.遍历每一个LOD结构中的Renderer组件,销毁其所在物体;

7.LOD Group组件遍历之后将其销毁。

代码如下:

using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;

namespace SK.Framework
{
    /// 
    /// LOD工具
    /// 
    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(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();
        }
    }
}

关注
打赏
1653184800
查看更多评论
立即登录/注册

微信扫码登录

0.0606s