目的:
检查Unity中资源是否重复,例如有两张贴图,明明是一张,却被复制为两份放在工程中,名字或者所在目录位置不同,这对于资源管理来说是很浪费的。因此需要写一个检查工具来检查项目中是否存在重复的资源。


思路:

Unity引擎内部对资源的管理是否有一个唯一标识,通过这个唯一标识来检查是否有多个资源的此标识相同。


相关知识:

1.Guid:

Unity会为每一个加入到Assets文件夹中的文件,创建一个同级同名的.meta文件,虽然文件类型的不同会影响这个.meta的具体内容,但它们都包含一个用来标记文件身份的File GUID

文件GUID提供了文件存储位置的抽象,这样一个文件GUID就对应一个具体的文件,因此我们才能随意移动这个文件而不破坏所有相关Object对这个文件的引用,而如果这个meta文件和物体不对应(比如我们SVN提交的时候没有提交修改的Meta文件),那么这个文件的引用就会丢失,造成不可预知的错误。

总结:存储了此文件和其他文件之间的引用关系

2.Localid:

标识了文件内部各个文件之间的引用关系,比如一个Prefab内部的各个gameObject之间的引用关系

3.InstanceId:

Guid和Localid更像是为了文件系统的管理而设计的,那么我们在unity中实际编写代码或者引擎对object进行管理的时候每次去获取这两个大字符串显然是效率很低的,因此Unity在对象层面又通过这两个Id设计了InstanceId。简单来说,我们在工程中可以通过InstanceId来获取任何一个Object的实例。这个Id通过GetInstanceID获得,返回物体的实例ID,即使是同一个Prefab,实例化出的不同GameObject的InstanceId也是不一样的

4.MD5

unity内部通过一种算法来计算资源文件的MD5码(一个字符串),这种方法类似于哈希,将不同文件计算出不同的MD5码,但不同于哈希值的计算,我们希望MD5最好永远不要重复(哈希值计算会出现重复冲突的情况),MD5一般被认为是Unity中区分不同文件的唯一标识,那么有人肯定会疑问,万一这个值真的重复了呢。不错,确实有比较厉害的黑客可以破解Unity所使用的的计算算法,使得不同的资源文件产生相同的MD5码,不过这是非常极端的情况。我们知道热更新的时候也会用到MD5码,来标识我们需要更新哪个文件,那么在这个过程我们最好是对MD5码进行加密的,以防有恶意软件攻击我们热更新的文件。

总结:资源文件的唯一标识,即使是同一个文件(不同名字,目录)这个值也是相同的,因此可以作为我们检查资源是否重复的比较标识


检查工具

思路:计算特定目录下文件的MD5码,将其存入字典中,如果字典中已经存在此key值,说明资源重复

关键:getTextureByte(),根据路径资源文件计算MD5码

using UnityEngine;

using System.Collections.Generic;

using System.IO;

using UnityEditor;

using System.Security.Cryptography;

public class ResCheckTool

{

    // md5和guidId不相同

    [MenuItem("Tools/Find Repeat", false, 10)]

    static private void Check()

    {

        // 定义查找路径

        string[] guids = Directory.GetFiles("Assets/Resources/", "*.*", SearchOption.AllDirectories);

        // 以MD5值为key的字典

        Dictionary<string, string> checkDic = new Dictionary<string, string>();

        string fileMd5 = string.Empty;

        for (int i = 0, count = guids.Length; i < count; i++)

        {

            // 过滤meta文件

            if (!guids[i].EndsWith(".meta"))

            {

                MD5 md5 = MD5.Create();

                byte[] md5bytes = md5.ComputeHash(getTextureByte(guids[i]));

                fileMd5 = System.BitConverter.ToString(md5bytes).Replace("-", "").ToLower();

                if (!checkDic.ContainsKey(fileMd5))

                {

                    checkDic.Add(fileMd5, guids[i]);

                }

                else

                {

                    Debug.Log("重复资源路径:" + guids[i] + "重复资源md5:" + fileMd5);

                }

            }

        }

    }

    /// <summary>

    /// 根据图片路径返回字节流,基本不会重复

    /// </summary>

    /// <param name="texturePath"></param>

    /// <returns></returns>

    static private byte[] getTextureByte(string assetsPath)

    {

        FileStream file = new FileStream(assetsPath, FileMode.Open);

        byte[] txByte = new byte[file.Length];

        file.Read(txByte, 0, txByte.Length);

        file.Close();

        return txByte;

    }

}

  https://www.jianshu.com/p/01a41a095a5c

Unity中检查重复的资源的更多相关文章

  1. Unity中资源打包成Assetsbundle的资料整理

    最近在研究Unity中关于资源打包的东西,网上看了一堆资料,这里做个整合,说整合,其实也就是Ctrl-C + Ctrl-V,不是原创 首先为了尊重原创,先贴出原创者的文章地址: http://blog ...

  2. 【Unity】Unity中资源动态载入的两种方式之AssetsBundle

    首先要说的是,我们的project中有2个脚本.各自是: Build(编辑器类脚本.无需挂载到不论什么物体).可是必需要把Build脚本放到Editor目录中 Load脚本,挂载到摄像机上<pr ...

  3. Unity中资源动态加载的几种方式比较

    http://blog.csdn.net/leonwei/article/details/18406103 初学Unity的过程中,会发现打包发布程序后,unity会自动将场景需要引用到的资源打包到安 ...

  4. 关于Unity中资源打包

    资源包详细说明 Unity很智能只会打包用到的资源,比如sharedassets0.assets中的shader资源,如果场景中有OBJ用到了shader那么就会有shader打进这个包,如果没有就不 ...

  5. unity中加载场景不销毁以及切换场景重复实例化

    问题描述 游戏开发中会有多个场景,有时会有这样的需求,我们需要保证场景跳转但是需要保持某个游戏对象不被销毁,比如:音乐 实现思路 unity中提供了DontDestroyOnLoad(),这个API ...

  6. 关于Unity中的UGUI优化,你可能遇到这些问题

    https://blog.uwa4d.com/archives/QA_UGUI-1.html 关于Unity中的UGUI优化,你可能遇到这些问题 作者:admin / 时间:2016年11月08日 / ...

  7. 「翻译」Unity中的AssetBundle详解(一)

    AssetBundles AssetBundle是一个存档文件,其中包含平台在运行时加载的特定资产(模型,纹理,预制,音频剪辑,甚至整个场景).AssetBundles可以表示彼此之间的依赖关系;例如 ...

  8. Unity中的资源管理

    一.AssetBundle 相关 Q1:Unity中的SerializedFile是怎么产生的?请问用Unload(false)可以清除吗?因为读取了Bundle里面的内容后已经赋值给其他物体了.而且 ...

  9. 单元测试在Unity中的应用

    项目描述:简单演示单元测试在Unity中的应用 项目地址:UnityTestRunner_Tutorial - SouthBegonia 项目版本:2020.3.20f1 项目用法:打开就用,代码都放 ...

  10. Unity中Mesh分解与边缘高亮加上深度检测

    一个比较简单的需求,不过遇到些坑,记录下. 房间有多个模型,每个模型可能多个SubMesh,点击后,需要能具体到是那个SubMesh,并且在这个SubMesh上显示边缘高光,以及能个性这单个SubMe ...

随机推荐

  1. java代码之美(1)

    Lambda 一.概述 1.什么是Lambda表达式 Lambda 表达式是一种匿名函数,简单地说,它是没有声明的方法,也即没有访问修饰符.返回值声明和名字. 它可以写出更简洁.更灵活的代码.作为一种 ...

  2. c代码部分封装为lib

    需求:将一个C工程中的核心代码封装为静态文件:lib. 环境 工具:VC6.0++ 语言:c 以封装一个DES工程为例 封装 (1)新建一个静态工程 (2)新建c文件和h文件 (3)挑选封装内容 在原 ...

  3. Volar Vetur 在 VSCode 里的配置

    VSCode 对 vue2 vue3 项目如何配置 1. 在 vscode 安装 vetur.Vue - Official(之前叫 Volar) 两个插件 2.你若是 vue3 项目,直接在你项目工作 ...

  4. java基础语法-package构造方法-继承-多态

    java中的包 - package 包:包中有很多的类,根据类的功能不同,我们可以创建不同的包. 包的主要功能: 包的主要功能:用于分类管理 包的基本语法 package 包的路径(完整路径,从第一个 ...

  5. EIP和NAT结合如何实现统一公网出口IP

    本文分享自天翼云开发者社区<EIP和NAT结合如何实现统一公网出口IP>,作者:j****n 通过EIP和NAT网关结合,为已绑定EIP的ECS实例统一公网出口IP,有利于更高效的管理互联 ...

  6. MYSQL数据空洞解析

    ## 背景引入 MYSQL中数据表A,在删除了一半的数据后,发现表空间的大小并没有减少,这是什么原因导致的呢? 定义 当对一定量数据执行delete操作时,MySQL将数据删除后进而导致页合并或者页删 ...

  7. Linux嵌入式设备怎么确定网络端口的速率

    Linux嵌入式设备怎么确定网络端口的速率 突发奇想,就是Linux下面我能不能查询到端口的速率,以此来判断要不要频繁的发送网络数据包呢? 或者更换包利用率更高的协议呢. 于是抱着这样的想法,我开始学 ...

  8. [BZOJ4671] 异或图 题解

    我能说什么!抽象了这! 看到 \(n\le 10\) 的黑题顿感大事不妙. 我们考虑设 \(f(i)\) 表示将 \(n\) 个点划分为至少 \(i\) 个连通块时的方案数.我们可以暴力枚举每个点在哪 ...

  9. Shell - [11] 开源Apache Zookeeper集群启停脚本

    一.集群角色部署 当前有Zookeeper集群如下 主机名 ctos79-01 ctos79-02 ctos79-03 Zookeeper ○ ○ ○ 二.脚本使用 三.脚本内容 #!/bin/bas ...

  10. MySQL - [06] 测试数据

    题记部分 一.死神测试数据 嗷嗷待"补" 二.火影忍者测试数据 -- 忍村表 create table hy_villages( VillageID INT PRIMARY KEY ...