Unity项目资源依赖视图丶合并丶清理

操作前,务必备份项目

using UnityEditor;
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

using Object = UnityEngine.Object;
using JsonUtility = Newtonsoft.Json.JsonUtility;

namespace AssetOptimizes
{
    public static class Style
    {
        private static GUIStyle _flow_node_hex_0;
        private static GUIStyle _flow_node_hex_0_on;
        private static GUIStyle _flow_node_0;
        private static GUIStyle _rich_text;
        private static GUIStyle _info1_text;
        private static GUIStyle _info2_text;

        static Style()
        {
            //默认字号(静态构造函数/在第一次访问Style静态类时调用)
            GUI.skin.label.fontSize = 12;
        }

        public static GUIStyle flow_node_0
        {
            get
            {
                if (_flow_node_0 == null)
                {
                    _flow_node_0 = GUI.skin.GetStyle("flow node 0");
                }
                return _flow_node_0;
            }
        }
        public static GUIStyle rich_text
        {
            get
            {
                if (_rich_text == null)
                {
                    _rich_text = new GUIStyle(GUI.skin.label);
                    _rich_text.richText = true;
                    _rich_text.alignment = TextAnchor.MiddleCenter;
                }
                return _rich_text;
            }
        }
        public static GUIStyle info1_text
        {
            get
            {
                if (_info1_text == null)
                {
                    //_info_text = new GUIStyle(GUI.skin.label);
                    _info1_text = new GUIStyle(GUI.skin.GetStyle("ObjectPickerResultsOdd"));
                    _info1_text.fontSize = 12;
                    _info1_text.richText = true;
                    _info1_text.alignment = TextAnchor.MiddleLeft;
                }
                return _info1_text;
            }
        }
        public static GUIStyle info2_text
        {
            get
            {
                if (_info2_text == null)
                {
                    _info2_text = new GUIStyle(GUI.skin.GetStyle("ObjectPickerPreviewBackground"));
                    _info2_text.fontSize = 12;
                    _info2_text.richText = true;
                    _info2_text.alignment = TextAnchor.MiddleLeft;
                }
                return _info2_text;
            }
        }
    }
    public static class AssetUtility
    {
        /// <summary> 获取文件的Hash值 </summary>
        public static string GetFileSha1(string path)
        {
            if (System.IO.File.Exists(path))
            {
                return HashFile(path, "sha1");
            }
            return string.Empty;
        }
        /// <summary> 获取文件的MD5值 </summary>
        public static string GetFileMD5(string path)
        {
            if (System.IO.File.Exists(path))
            {
                return HashFile(path, "md5");
            }
            return string.Empty;
        }


        public static string GetSizeName(long _size)
        {
            var str = _size + "B";
            var size = (float)_size;
            if (size > 1024)
            {
                size /= 1024;
                str = size.ToString("f1") + "KB";
            }
            if (size > 1024)
            {
                size /= 1024;
                str = size.ToString("f1") + "MB";
            }
            return str;
        }

        /// <summary> 刷新Asset资产 </summary>
        public static void RefreshAssetForce()
        {
            //刷新文件的数据(转换效率慢)
            //EditorSettings.serializationMode = SerializationMode.ForceBinary;
            //EditorSettings.serializationMode = SerializationMode.ForceText;
            //刷新资源视图
            AssetDatabase.Refresh();
        }


        static string HashFile(string path, string type)
        {
            System.IO.FileStream stream = null;
            try
            {
                stream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                //计算Hash值
                System.Security.Cryptography.HashAlgorithm algorithm;
                switch (type?.ToLower())
                {
                    case "md5":
                        algorithm = System.Security.Cryptography.MD5.Create();
                        break;
                    case "sha1":
                        algorithm = System.Security.Cryptography.SHA1.Create();
                        break;
                    default:
                        throw new Exception("只能使用 sha1 或 md5");
                }
                byte[] hash_bytes = algorithm.ComputeHash(stream);

                return BitConverter.ToString(hash_bytes).Replace("-", "");
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }
            finally
            {
                stream?.Close();
            }

            return string.Empty;
        }
    }

    //资源优化编辑窗口
    public class AssetManagerWindow : EditorWindow
    {
        public enum ViewState
        {
            /// <summary> 未选中状态 </summary>
            NONE = -1,
            /// <summary> 全部资源 </summary>
            ALL = 0,
            /// <summary> 未使用资源 </summary>
            UNUSED = 1,
            /// <summary> 重复资源 </summary>
            MERGE = 2,
        }
        public enum OrderType
        {
            /// <summary>
            /// 大小
            /// </summary>
            Size,
            /// <summary>
            /// 类型
            /// </summary>
            Type,
            /// <summary>
            /// 引用计数
            /// </summary>
            DependentCount,
            /// <summary>
            /// 被引用计数
            /// </summary>
            DependentUsedCount,
        }
        public enum AssetType
        {
            /// <summary> 全选 </summary>
            Everything = -1,
            /// <summary> 纹理资源 </summary>
            Texture = 1,
            /// <summary> 文本资源 </summary>
            TextAsset = 2,
            /// <summary> 音频资源 </summary>
            Audio = 4,
            /// <summary> C#脚本 </summary>
            MonoScript = 8,
            /// <summary> Mat材质球 </summary>
            Mat = 16,
            /// <summary> Prefab资源 </summary>
            Prefab = 32,
            /// <summary> Scene资源 </summary>
            Unity = 64,
            /// <summary> Material资源 </summary>
            Material = 128,
            /// <summary> Meta文件 </summary>
            Meta = 256,
            /// <summary> 文件夹 </summary>
            Folder = 512,
            /// <summary> 其他类型 </summary>
            Other = 1024,
        }
        public class Asset
        {
            /// <summary> 资源路径 </summary>
            public string path { get; private set; }
            //名称
            public string name { get; private set; }
            /// <summary> 资源类型 </summary>
            public AssetType type { get; private set; } = AssetType.Other;
            /// <summary> 资源类型ID </summary>
            public int typeNum { get; private set; } = -1;

            /// <summary> GUID(唯一标识符) </summary>
            public string guid { get; private set; }

            /// <summary> 资源MD5吗(用于判断文件是否一致) </summary>
            public string md5 { get; private set; }
            /// <summary> 缓存图标 </summary>
            public Texture cacheIcon { get; private set; }
            /// <summary> 资源大小 </summary>
            public long size { get; private set; } = 0;
            /// <summary> 资源是否被选中 </summary>
            public bool select = false;

            /// <summary> 依赖的资源路径 </summary>
            public List<Asset> dependencies { get; } = new List<Asset>();
            /// <summary> 被其他资源引用 </summary>
            public List<Asset> dependenciesUsed { get; } = new List<Asset>();
            /// <summary> 相同文件列表 </summary>
            public List<Asset> sameList { get; } = new List<Asset>();
            /// <summary> 内嵌Spirte信息 </summary>
            public List<SpriteMetaData> spriteSheet { get; } = new List<SpriteMetaData>();
            /// <summary> Texture导入模式 </summary>
            public SpriteImportMode spriteImportMode = SpriteImportMode.None;


            private string sizeName = null;

            public Asset(string path)
            {
                this.path = path;
                this.md5 = AssetUtility.GetFileMD5(path);
                this.guid = AssetDatabase.AssetPathToGUID(path);
                this.name = AssetDatabase.LoadMainAssetAtPath(path)?.name;
                this.cacheIcon = AssetDatabase.GetCachedIcon(path);
                //Type
                this.type = AssetType.Other;
                if (path.EndsWith(".meta"))
                    this.type = AssetType.Meta;
                else if (path.EndsWith(".jpg") || path.EndsWith(".png"))
                    this.type = AssetType.Texture;
                else if (path.EndsWith(".txt") || path.EndsWith(".json"))
                    this.type = AssetType.TextAsset;
                else if (path.EndsWith(".mp3") || path.EndsWith(".wav"))
                    this.type = AssetType.Audio;
                else if (path.EndsWith(".mat") || path.EndsWith(".material"))
                    this.type = AssetType.Material;
                else if (path.EndsWith(".cs"))
                    this.type = AssetType.MonoScript;
                else if (path.EndsWith(".prefab"))
                    this.type = AssetType.Prefab;
                else if (path.EndsWith(".unity"))
                    this.type = AssetType.Unity;
                else if (System.IO.Directory.Exists(path))
                    this.type = AssetType.Folder;
                this.typeNum = Convert.ToInt32(this.type);

                //Debug.Log(AssetDatabase.GetMainAssetTypeAtPath(path));

                if (System.IO.File.Exists(path))
                {
                    var info = new FileInfo(path);
                    this.size = info.Length;
                }
            }
            public string GetSizeName()
            {
                if (sizeName == null)
                {
                    var size = (float)this.size;
                    sizeName = size.ToString("f0") + "B";
                    if (size > 1024)
                    {
                        size /= 1024;
                        sizeName = size.ToString("f1") + "KB";
                    }
                    if (size > 1024)
                    {
                        size /= 1024;
                        sizeName = size.ToString("f2") + "MB";
                    }
                }
                return sizeName;
            }
            public int GetInstanceID()
            {
                return AssetDatabase.LoadAssetAtPath<Object>(path).GetInstanceID();
            }
            public string GetDependencies()
            {
                var temp = "";
                for (int i = 0; i < dependencies.Count; i++)
                {
                    temp += "\n" + (i + 1) + "." + dependencies[i].path;
                }
                return temp;
            }
            public string GetDependenciesUsed()
            {
                var temp = "";
                for (int i = 0; i < dependenciesUsed.Count; i++)
                {
                    temp += "\n" + (i + 1) + "." + dependenciesUsed[i].path;
                }
                return temp;
            }
            public string GetSameFiles()
            {
                var temp = "";
                for (int i = 0; i < sameList.Count; i++)
                {
                    temp += "\n" + (i + 1) + "." + sameList[i].path;
                }
                return temp;
            }
            public string GetSpriteSheet()
            {
                if (spriteImportMode != SpriteImportMode.None)
                {
                    var temp = "\t" + Enum.GetName(typeof(SpriteImportMode), spriteImportMode);
                    for (int i = 0; i < spriteSheet.Count; i++)
                    {
                        temp += "\n" + (i + 1) + ".Name:" + spriteSheet[i].name + "\tRect:" + spriteSheet[i].rect;
                    }
                    return temp;
                }
                return "";
            }
            public string GetInfo()
            {
                string str = @"[信息] <b>Name:</b>{0}    <b>GUID:</b>{1}
<b>Path:</b>{2}
<b>Size:</b>{3}({4})
<b>MD5:</b>{5}
<b>依赖:</b>{6}
<b>被依赖:</b>{7}
<b>相同文件:</b>{8}
<b>纹理模式:</b>{9}
            ";
                return string.Format(str, name, guid, path, GetSizeName(), size, md5,
                 GetDependencies(), GetDependenciesUsed(), GetSameFiles(), GetSpriteSheet());
            }
        }

        //当前按钮状态
        private ViewState menuState = ViewState.NONE;
        private int viewId = -1;
        private bool viewRefresh = true;
        //ScrollView 进度条
        private Vector2 contentVec2;

        //所有资源列表
        private Dictionary<string, Asset> assetsMappingGuids = new Dictionary<string, Asset>();
        private List<Asset> assets = new List<Asset>();
        private List<Asset> assetsAll = new List<Asset>();
        //是否获取所有资源信息
        private bool completeAllAssets = false;
        //是否建立起依赖引用信息
        private bool completeDependencies = false;
        ///是否建立MD5比对信息
        private bool completeAllMd5 = false;


        //渲染页数
        private int page = 1;
        private int pageSize = 20;
        //选择的资源列表
        private List<Asset> selectAssets = new List<Asset>();
        //选择删除的资源列表
        private List<Asset> selectDelete = new List<Asset>();
        //选择合并的资源列表
        private List<List<Asset>> selectMerge = new List<List<Asset>>();

        //选择的类型
        private AssetType selectType = AssetType.Everything;
        //排序规则
        private OrderType orderType = OrderType.Size;
        //是否升序Ascending/降序Descending 
        private bool ascending = false;
        //筛选条件
        private string search = null;

        //filter 需要过滤的字段
        private string filterString;
        private string filterDefault = "Editor;Gizmos;Plugins;Resources;StreamingAssets;Editor Default Resources;";
        private string[] filter;


        [MenuItem("Tools/AssetsManager/Manager")]
        static AssetManagerWindow InitWindow()
        {
            AssetManagerWindow window = (AssetManagerWindow)EditorWindow.GetWindow(typeof(AssetManagerWindow), false, "Manager");
            window.Show();
            return window;
        }

        [MenuItem("Assets/Check/Dependencies")]
        static void CheckDependencies()
        {
            var path = Selection.activeObject != null ? AssetDatabase.GetAssetPath(Selection.activeObject) : null;
            if (!string.IsNullOrEmpty(path) && File.Exists(path))
            {
                var dependencies = AssetDatabase.GetDependencies(path);
                var temp = "";
                for (int i = 0; i < dependencies.Length; i++)
                {
                    temp += "\n" + (i + 1) + "." + dependencies[i];
                }
                Debug.Log(string.Format("<b>Path:</b>{0} \n<b>依赖:</b>{1}", path, temp));
            }
        }
        [MenuItem("Assets/Check/DependenciesUsed")]
        static void CheckDependenciesUsed()
        {
            var path = Selection.activeObject != null ? AssetDatabase.GetAssetPath(Selection.activeObject) : null;
            if (!string.IsNullOrEmpty(path) && File.Exists(path))
            {
                //Dependencies
                var temp1_i = 0;
                var temp1 = "";
                var dependencies = AssetDatabase.GetDependencies(path);
                for (int i = 0; i < dependencies.Length; i++)
                {
                    temp1 += "\n" + (temp1_i + 1) + "." + dependencies[i];
                    temp1_i++;
                }
                //DependenciesUsed
                var temp2_i = 0;
                var temp2 = "";
                string[] paths = AssetDatabase.GetAllAssetPaths();
                for (int i = 0; i < paths.Length; i++)
                {
                    try
                    {
                        var cancel = EditorUtility.DisplayCancelableProgressBar(string.Format("检查依赖中({0}/{1})", i, paths.Length), paths[i], (float)i / paths.Length);
                        if (cancel)
                        {
                            InfoWindow.Log("取消检查:" + path);
                            EditorUtility.ClearProgressBar();
                            return;
                        }
                        i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值