检测Unity客户端无效的预设资源

扫描Resource目录里面可能未使用的prefab,输出一个可能无效的资源列表

可能未使用的prefab满足以下规则:

1、不被其他prefab和场景直接引用----遍历GUID校验排除

2、不被其他prefab和场景间接引用,prefab脚本里面传入其他预设的名称或者路径----遍历prefab名称排除

3、不被代码里面直接引用----遍历CS文件校验prefab名称排除

为什么说是可能未使用的prefab,因为还有一种情况:

4、不被代码间接引用,如预设Anniver_01,在代码中是"Anniver_"+number,这种暂时没有好办法解决。

 static public void checkByGUIDPrefab(Dictionary<string, PrefabData> guidPrefabDic, List<string> allResPathList)
        {
            //校验GUID
            int nIndex = 0;
            for (nIndex = 0; nIndex != allResPathList.Count; ++nIndex)
            {
                if (EditorUtility.DisplayCancelableProgressBar("正在扫描预设与场景中--校验GUID引用", "收集中..." + nIndex, (nIndex*1.0f)/ allResPathList.Count))
                {
                    EditorUtility.ClearProgressBar();
                    return;
                }
                checkReference(guidPrefabDic, allResPathList[nIndex], true);
            }

            //校验预设里面包含其他预设的名称
            for (nIndex = 0; nIndex != allResPathList.Count; ++nIndex)
            {
                if (EditorUtility.DisplayCancelableProgressBar("正在扫描预设与场景中--校验预设名引用", "收集中..." + nIndex, (nIndex * 1.0f) / allResPathList.Count))
                {
                    EditorUtility.ClearProgressBar();
                    return;
                }
                checkNameReference(guidPrefabDic, allResPathList[nIndex]);
            }

            //除了预设和场景引用 还有代码引用
            List<string> resPathList = new List<string>();
            string[] codePath = Directory.GetFiles("Assets", "*.cs", SearchOption.AllDirectories);
            foreach (string fi in codePath)
            {
                resPathList.Add(fi);
            }

            //校验代码引用
            for (nIndex = 0; nIndex != resPathList.Count; ++nIndex)
            {
                if (EditorUtility.DisplayCancelableProgressBar("正在扫描CS源码中--校验预设名引用", "收集中..." + nIndex, (nIndex * 1.0f) / resPathList.Count))
                {
                    EditorUtility.ClearProgressBar();
                    return;
                }
                checkReference(guidPrefabDic, resPathList[nIndex], false);
            }
            //还有一些主要是为了Alpha通道分离 将一张图片转换成了预设
            //判断在OriginRes中是否有同名的.png文件存在 如果存在则淘汰掉

            string filePath = "Assets/_OriginRes/";
            string[] fis = Directory.GetFiles(filePath, "*.png", SearchOption.AllDirectories);

            //写文件吧::::
            List<string> unUsePrefabList = new List<string>();
            foreach (string key in guidPrefabDic.Keys)
            {
                if (!guidPrefabDic[key].isReference && !isExistSameNamePngFile(fis, guidPrefabDic[key].fileName))
                {
                    //Assets/Resources/_NewPanel/BillRecordPanel/BillRecordPanel.prefab 路径转文件名
                    //codeSrcPrefab.Add(AssetDatabase.GUIDToAssetPath(key), 1);
                    //Debug.LogError("找到未使用的预设名字:" + guidPrefabDic[key].fileName);
                    unUsePrefabList.Add(guidPrefabDic[key].fileName);
                    unUsePrefabPathList.Add(AssetDatabase.GUIDToAssetPath(key));
                }
            }
            EditorUtility.DisplayCancelableProgressBar("扫描结束", "写入本地文件...", 1f);
            
            File.WriteAllLines("Assets/possible_unused_prefab.txt", unUsePrefabPathList.ToArray());
            EditorUtility.ClearProgressBar();

            //for (int i = 0; i < unUsePrefabPathList.Count; i++)
            //{
            //    System.IO.File.Copy(unUsePrefabPathList[i], @"Assets/Resources/Test1/" + Path.GetFileNameWithoutExtension(unUsePrefabPathList[i]), true);
            //}
            //拷贝文件至指定目录 试试看

        }
        /// <summary>
        /// 校验GUID或者名称
        /// </summary>
        /// <param name="guidPrefabDic"></param>
        /// <param name="resFilePath"></param>
        /// <param name="checkGUID"></param>
        static public void checkReference(Dictionary<string, PrefabData> guidPrefabDic, string resFilePath, bool checkGUID = true)
        {
            FileStream fs = new FileStream(resFilePath, FileMode.Open, FileAccess.Read);
            byte[] buff = new byte[fs.Length];
            fs.Read(buff, 0, (int)fs.Length);
            string strText = Encoding.Default.GetString(buff);
            fs.Close();

            foreach (string key in guidPrefabDic.Keys)
            {
                if (guidPrefabDic[key].isReference == true)
                {
                    continue;
                }
                int nStar = 0;
                string checkStr = "";
                if (checkGUID)
                {
                    checkStr = key;
                }
                else
                {
                    checkStr = guidPrefabDic[key].fileName;
                }
                nStar = strText.IndexOf(checkStr);
                if (nStar != -1)
                {
                    guidPrefabDic[key].isReference = true;
                }
            }
        }

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java进阶架构师

03:SpringBoot整合SpringDataJPA实现数据库的访问(二)

首先回忆一下,前面我们创建studentRepo类继承JpaRepository<T,ID>接口,即可实现最基本的crud。如下:

822
来自专栏Python攻城狮

Django教程(三)- Django表单Form1.Form 基本使用2.Form中字段及插件3.通过Django表单Form来完成需求4.自定义验证验证规则

创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;

1724
来自专栏大内老A

IoC+AOP的简单实现

对EnterLib有所了解的人应该知道,其中有一个名叫Policy Injection的AOP框架;而整个EnterLib完全建立在另一个叫作Unity的底层框...

2039
来自专栏枕边书

PHP递归创建多级目录(一道面试题的解题过程)

今天看到一道面试题,要写出一个可以创建多级目录的函数: 我的第一个感觉就是用递归创建,具体思路如下: function Directory($dir){   ...

2377
来自专栏坚毅的PHP

my php & mysql FAQ

php中文字符串长度及定长截取问题使用str_len("中国") 结果为6,php系统默认一个中文字符长度为3,可改用mb_strlen函数获得长度,mb_su...

3756
来自专栏芋道源码1024

哪个更快:Java 堆还是本地内存

使用Java的一个好处就是你可以不用亲自来管理内存的分配和释放。当你用new关键字来实例化一个对象时,它所需的内存会自动的在Java堆中分配。堆会被垃圾回收器进...

1104
来自专栏极客猴

Django 学习笔记之模型高级用法(上)

前面有两篇文章简单介绍 Django 的模型,这一部分算是基础知识。我自己近期也总做了下总结,将花大概两篇的篇幅来分享下模型的一些高级用法。

683
来自专栏Charlie's Road

<Solidity学习系列四>使用编译器

Solidity存储库的一个构建目标是solc,solidity命令行编译器。 使用solc --help为您提供所有选项的解释。 编译器可以生成各种输出,范围...

1392
来自专栏分布式系统和大数据处理

Command模式入门

提起Command模式,我想没有什么比遥控器的例子更能说明问题了,本文将通过它来一步步实现GOF的Command模式。

892
来自专栏名山丶深处

springboot集成jpa

2375

扫码关注云+社区