之所以写这个插件呢,就是为了方便整理项目中的资源文件,我记得之前好像也用了这么一个插件,但是也没去找,还是自己动手写一个吧,需要什么功能就看自己的需求。

在项目的过程中呢,已经写了一个插件来管理材质,但是跟随模型导入的图片却越来越多,也是自己跟美术沟通不到位,导致根本没办法保证图片的命名规则或者是否有重复的图片,再加上不断的删除或者更新模型,项目中一些无用的图片也堆积了不少。我尝试了自己手动整理,但是没有命名规则的图片和一些靠缩略图甚至无法分辨是不是一样的图片,这样的工作,就相当无力了。

于是呢,就完成了这么一个插件:

1.点击Organize Resources/Editor Window打开插件,点击未使用资源按钮,这里就会罗列出Assets文件夹里所有未被引用的资源,当然当前未被引用肯定不代表他完全没用,还是得靠自己确认然后手动删除

2.点击全部资源,他就会输出所有的文件,并可以通过按钮输出他的GUID、应用和被引用的其他Assets路径,这里主要理清一些资源的关联关系

3.点击重复资源按钮,就可以分类显示当前重复有哪些文件,这里的文件重复判断后面有具体介绍,点击合并按钮,就可以清除掉多余的资源,如果其他本地资源引用了这个文件,合并的文件也会自动替换上去,不用担心其他文件引用会丢失

这里New Material材质引用了fish 2图片,然后我在合并界面随便点一个fish后面的合并按钮

然后,多余的图片已经被清除了,而本来引用fish 2的材质New Material,也变成了引用fish图片,这里就是我当前需要的主要功能

上面的呢,是大概介绍了一些插件的功能,接下来就展示一下主要的功能代码:

1.获取当前Object引用了其他哪些Object,这里在unity是有接口的,返回的就是引用了其他的Object的路径:

  1. string[] _OtherPaths = AssetDatabase.GetDependencies(_PathValue);

2.获取当前Object被其他那些Object引用了,说着感觉有点绕,不过功能也就是根据上面的反正写一个查找功能,获取其他Obejc的引用路径,再与当前的的Object匹配,这里的主要判断依据靠的是Object的GUID

  1. #region 获取其他引用Assets的路径
  2. string[] GetUseAssetPaths(string _AssetPath)
  3. {
  4. List<string> _AssetPaths = new List<string>();
  5. //使用GUID作为判断标准
  6. string _AssetGUID = AssetDatabase.AssetPathToGUID(_AssetPath);
  7. //遍历所有Assets
  8. for (int i = 0; i < _AllAssetsPaths.Count; i++)
  9. {
  10. if (_AllAssetsPaths[i] == _AssetPath)
  11. continue;
  12.  
  13. string[] _OtherPaths = AssetDatabase.GetDependencies(_AllAssetsPaths[i]);
  14. if (_OtherPaths.Length > 1)
  15. {
  16. for (int j = 0; j < _OtherPaths.Length; j++)
  17. {
  18. string _OtherGUID = AssetDatabase.AssetPathToGUID(_OtherPaths[j]);
  19. if (_AssetGUID == _OtherGUID)
  20. {
  21. _AssetPaths.Add(_AllAssetsPaths[i]);
  22. }
  23. }
  24. }
  25. }
  26. return _AssetPaths.ToArray();
  27. }
  28. #endregion

3.获取相同的文件,开始使用正常的文件MD5值的验证,发现了一个问题,就是对于外部资源(从外面导入的资源,比如Texture、fbx)的验证是正常的,但是对于unity内部资源(在unity内部创建的文件,比如prefab、material)就不对了,后来读取内部资源的Text发现,他在内部有Object的名称,而Unity里的文件又不能重名,于是文件就不一样了,后来我就直接将他有名称的那行数据先删掉再来获取MD5值,才成功判断相同文件

获取相同文件

  1. string[] GetSameFilePaths(string _PathValue)
  2. {
  3. List<string> _AssetPaths = new List<string>();
  4.  
  5. string _AssetMD5 = GetFileMD5(_PathValue);
  6. //遍历所有Assets
  7. for (int i = 0; i < _AllAssetsPaths.Count; i++)
  8. {
  9. if (_AllAssetsPaths[i] == _PathValue)
  10. continue;
  11. if (_AssetMD5 == GetFileMD5(_AllAssetsPaths[i]))
  12. _AssetPaths.Add(_AllAssetsPaths[i]);
  13.  
  14. }
  15. return _AssetPaths.ToArray();
  16. }

获取文件的MD5值

  1. #region 获取文件的MD5值
  2. string GetFileMD5(string _PathValue)
  3. {
  4. //判断是否为本地资源 因为本地文件里有文件名称 但是在资源名称又不能重复 于是需要去掉名称 来检测md5值
  5. Object _ObejctValue = AssetDatabase.LoadAssetAtPath<Object>(_PathValue);
  6. bool _isNative =AssetDatabase.IsNativeAsset(_ObejctValue);
  7. string _FileMD5 = "";
  8. string _TemPath = Application.dataPath.Replace("Assets", "");
  9.  
  10. if (_isNative)
  11. {
  12. string _TempFileText = File.ReadAllText(_TemPath + _PathValue).Replace("m_Name: " + _ObejctValue.name,"");
  13.  
  14. System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
  15. //将字符串转换为字节数组
  16. byte[] fromData = System.Text.Encoding.Unicode.GetBytes(_TempFileText);
  17. //计算字节数组的哈希值
  18. byte[] toData = md5.ComputeHash(fromData);
  19. _FileMD5 = "";
  20. for (int i = 0; i < toData.Length; i++)
  21. {
  22. _FileMD5 += toData[i].ToString("x2");
  23. }
  24. }
  25. else
  26. {
  27. try
  28. {
  29.  
  30. FileStream fs = new FileStream(_TemPath + _PathValue, FileMode.Open);
  31.  
  32. System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
  33. byte[] retVal = md5.ComputeHash(fs);
  34. fs.Close();
  35. _FileMD5 = "";
  36. for (int i = 0; i < retVal.Length; i++)
  37. {
  38. _FileMD5 += retVal[i].ToString("x2");
  39. }
  40. }
  41. catch (System.Exception ex)
  42. {
  43. Debug.Log(ex);
  44. }
  45. }
  46. return _FileMD5;
  47. }
  48. #endregion

4.合并时,当前文件替换掉其他被清除的文件,这里也是比较简单的,其他Object也是通过文件的GUID来引用文件,这里主要将他的GUID替换掉就可以

  1. #region 合并
  2. void OnRepeatMerge(string _PathValue,List<string> _ListValue)
  3. {
  4. string _FixedGUID= AssetDatabase.AssetPathToGUID(_PathValue);
  5. string _AssetsPath = Application.dataPath.Replace("Assets", "");
  6.  
  7. for (int i = 0; i < _ListValue.Count; i++)
  8. {
  9. if (_PathValue == _ListValue[i])
  10. continue;
  11. string[] _OtherPaths = GetUseAssetPaths(_ListValue[i]);
  12.  
  13. bool _isOtherNative = true;
  14. string _OldGUI = AssetDatabase.AssetPathToGUID(_ListValue[i]);
  15. for (int j = 0; j < _OtherPaths.Length; j++)
  16. {
  17. Object _OtherUseAsset = AssetDatabase.LoadAssetAtPath<Object>(_OtherPaths[j]);
  18. if (AssetDatabase.IsNativeAsset(_OtherUseAsset))
  19. {
  20. string _RealAllText = File.ReadAllText(_AssetsPath+ _OtherPaths[j]).Replace(_OldGUI,_FixedGUID);
  21. File.WriteAllText(_AssetsPath + _OtherPaths[j], _RealAllText);
  22. }
  23. else
  24. _isOtherNative = false;
  25. }
  26. //如果没有外部资源引用他 就删除
  27. if (_isOtherNative)
  28. {
  29. AssetDatabase.DeleteAsset(_ListValue[i]);
  30. _ListValue.RemoveAt(i);
  31. i--;
  32. }
  33. }
  34. AssetDatabase.Refresh();
  35. OnRepeatClick();
  36. }
  37. #endregion

5.最后总结,在相对较大的项目中,因为会遍历所有的文件,插件的反应速度就不那么尽如人意,想想也不会时时来整理资源,所以也暂时忽略掉了,然后,插件的功能也会在后面慢慢完善

工程链接:https://github.com/coding2233/OrganizeResources

Unity 资源管理插件的更多相关文章

  1. 开发unity DLL插件

    最近开发一款设备的SDK,想着要开发unity版本,怎么做呢?首先想到的就是在外部编写相关的驱动程序然后集成成几个dll作为unity的SDK使用了.So,我就开始了unity外部插件的研究之旅了. ...

  2. (转)Unity Cinemachine插件,实现单目标和多目标之间切换

    Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换*版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 Cinemachine插件 ...

  3. 细谈unity资源管理的设计

    一.概要 本文主要说说Unity是如何管理的,基于何种方式,基于这种管理方式,又该如何规划资源管理,以及构建bundle,是后面需要详细讨论的. 二.Unity的资源管理方式 2.1 资源分类 uni ...

  4. 开源Unity小插件CheatConsole

    我们在开发游戏的过程中,通常都需要一些快捷的方式来进行一些非常规的测试,这些功能一般被称作控制台或者GM指令,比如虚幻竞技场中,可以使用~键呼出控制台,输入一些指令即可进行快捷设置,比如设置分辨率,全 ...

  5. 编写 Unity Editor 插件

    Editor Style Viewer 在开发过程中,我喜欢编写一些辅助的Editor插件,方便在游戏开发过程进行调试. 下面是摘自Asset Store的一个查看Unity 默认GUI样式的小工具 ...

  6. 【转】unity地形插件T4M使用帮助

    unity的地形系统在手机游戏中因为效率问题基本无法使用,只能通过T4M这个地形插件来进行优化制作.下面大概讲解一下使用流程及方法. 先中U3D里面用自带的地形系统刷出想要的地形和贴图.贴图可以大概刷 ...

  7. unity Dotween插件的简单介绍及示例代码

    unity里面做插值动画的插件有许多,比较常见的有itween.hotween.dotween.根据大家的反馈和实际体验来说,dotween插件在灵活性.稳定性.易用性上都十分突出.这里简单介绍下它的 ...

  8. Unity给力插件之ShaderForge(一)

    这是一个用来制作shader的插件,也是一个很好的学习shader的工具.这个插件上手很容易,但是要用它来制作理想的Shader,需要下点功夫. 这儿先列举出基础知识,以及我的一些实践.以后我还会继续 ...

  9. Unity给力插件之MeshBaker

    这是一个用来合并网格.材质.贴图的插件. 其实网上也有一些比较详细的使用说明,但是真实操作起来时,总是有一些搞不清bug.而且,作为功能比较全的插件,在Unity版本更新时,也难免会一些不兼容的地方. ...

随机推荐

  1. mybatis学习三

    Mybatis与pageHelper分页:    分页分为假分页和真分页对应的专业术语叫做逻辑分页和物理分页    逻辑分页:将所有的数据从数据库查询出来,根据需求截取符合要求的数据返回,方便统一但效 ...

  2. [SDOI 2011]黑白棋

    Description 题库链接 给出一个 \(1\times n\) 的棋盘,棋盘上有 \(k\) 个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 \( ...

  3. UVA129 —— Krypton Factor (氪因素)

    Input and Output In order to provide the Quiz Master with a potentially unlimited source of question ...

  4. cocos2d-x-3.0beta2创建项目遇到“UnicodeDecodeError: 'ascii' codec can't decode byte 0xd7 in position 9: ordinal not in range(128)”的问题

    在Windows平台下 用cocos2d-x-3.0beta2版本下的create_project.py工具创建项目 但是遇到如下问题:UnicodeDecodeError: 'ascii' code ...

  5. c语言的第三次作业

    (一)改错题 计算f(x)的值:输入实数x,计算并输出下列分段函数f(x)的值,输出时保留1位小数. 输入输出样例1: Enterr x: 10.0 f(10.0) = 0.1 输入输出样例2: En ...

  6. js error

    0x800a0259 - JavaScript 运行时错误: 未知的运行时错误 <p id="navigatorInfo"></p> var txt = & ...

  7. vue中的eventBus

    在vue2中,父子组件传递数据,父组件可以直接传递数据进子组件,而子组件通过调用父组件传递进来的方法,将自己的数据传递回去. 那兄弟组件之间,或者是兄弟组件的子组件之间如何传递呢? 当然vuex是一种 ...

  8. promise应用及原生实现promise模型

    一.先看一个应用场景 发送一个请求获得用户id, 然后根据所获得的用户id去执行另外处理.当然这里我们完全可以使用回调,即在请求成功之后执行callback; 但是如果又添加需求呢?比如获得用户id之 ...

  9. Python中如何将二维列表转换成一维列表

    已知:a = [(4,2,3), (5, 9, 1), (7,8,9)]希望将二维列表转换成一维列表:["4,2,3", "5, 9, 1", "7, ...

  10. 剑指架构师系列-Nginx的安装与使用

    Nginx可以干许多事情,在这里我们主要使用Nginx的反向代理与负载均衡功能. 1.Nginx的下载安装 在安装Nginx前需要安装如下软件: GCC  Nginx是C写的,需要用GCC编译 PCR ...