using System; using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; /// /// 扫描出全部资源中,非GameObject,也没有被任何GameObject或者Scene引用的资源; /// public class UnusedResourceToList { [MenuItem("ResourceTool/Scan All Assets")] public static void Get() { var instance = new UnusedResourceToList(); instance.Start(); } private List _assetList; private List _failAsset; private string[] _testList; private int _index; protected void Start() { _failAsset = new List(); var assetPaths = AssetDatabase.GetAllAssetPaths(); _assetList = new List(assetPaths.Length); for (var i = 0; i < assetPaths.Length; i++) { const string assetHeader = "Assets"; if (assetPaths[i].StartsWith(assetHeader) && !assetPaths[i].StartsWith("Assets/StreamingAssets")) { var filePath = Application.dataPath + assetPaths[i].Substring(assetHeader.Length); // 排除文件夹 if (File.Exists(filePath)) { var extension = Path.GetExtension(assetPaths[i]); if (string.IsNullOrEmpty(extension) || !extension.Equals(".prefab", StringComparison.OrdinalIgnoreCase) && !extension.Equals(".unity", StringComparison.OrdinalIgnoreCase) && !extension.Equals(".cs", StringComparison.OrdinalIgnoreCase) && !extension.Equals(".js", StringComparison.OrdinalIgnoreCase)) { var item = new ResourceUsageData(assetPaths[i], extension); if (assetPaths[i].Contains("/Resources/")) item.inResource = true; _assetList.Add(item); } } } } _testList = (from assetPath in AssetDatabase.GetAllAssetPaths() let extension = Path.GetExtension(assetPath) where !string.IsNullOrEmpty(extension) && ( extension.Equals(".prefab", StringComparison.OrdinalIgnoreCase) || extension.Equals(".unity", StringComparison.OrdinalIgnoreCase) || assetPath.Contains("/Resources/")) select assetPath).ToArray(); _index = 0; EditorApplication.update += OnEditorUpdate; } /// /// 从Scene和GameObject建立连接库 /// private void OnEditorUpdate() { var finish = false; try { if (_index < _testList.Length) { var path = _testList[_index]; var dependencies = AssetDatabase.GetDependencies(path); for (var i = 0; i < dependencies.Length; i++) { if (!string.IsNullOrEmpty(dependencies[i]) && !path.Equals(dependencies[i])) { var data = GetListItem(dependencies[i]); if (data != null) { data.refCount++; if (path.Contains("/Resources/")) data.refByResource = true; } } } Debug.Log(string.Format("扫描资源{0} / {1}", _index, _testList.Length)); _index++; } else { Debug.LogWarning("完成全部扫描"); finish = true; } } catch (Exception e) { Debug.LogError(e.ToString()); Debug.LogError(string.Format("扫描失败于{0}", _index)); _failAsset.Add(_testList[_index]); _index++; } if (finish) WriteToFile(); } private void WriteToFile() { EditorApplication.update = null; _assetList.Sort(CompareMethod); var builder = new StringBuilder(); builder.Append("Asset"); builder.Append('\t'); builder.Append("Extension"); builder.Append('\t'); builder.Append("IsResource"); builder.Append('\t'); builder.Append("RefByResource"); builder.Append('\t'); builder.Append("RefCount"); var filePath = Application.dataPath + "/_Test/AllAssetSituation.txt"; for (var i = 0; i < _assetList.Count; i++) _assetList[i].WriteToBuilder(builder); File.WriteAllText(filePath, builder.ToString()); Debug.LogWarning("结果输出到文件 " + filePath); if (_failAsset.Count > 0) { Debug.LogError("扫描资源失败数目 " + _failAsset.Count); for (var i = 0; i < _failAsset.Count; i++) Debug.LogError("扫描失败于 " + _failAsset[i]); } } private static int CompareMethod(ResourceUsageData source, ResourceUsageData target) { var result = source.inResource.CompareTo(target.inResource); if (result == 0) result = source.refCount.CompareTo(target.refCount); if (result == 0) result = string.Compare(source.assetPath, target.assetPath, StringComparison.Ordinal); return result; } private ResourceUsageData GetListItem(string assetPath) { ResourceUsageData data = null; for (var i = 0; i < _assetList.Count; i++) if (_assetList[i].assetPath.Equals(assetPath)) { data = _assetList[i]; break; } return data; } } public class ResourceUsageData { public string assetPath; public string extension; public Type assetType; public int refCount; public bool inResource; public bool refByResource; public ResourceUsageData(string path, string extension) { assetPath = path; this.extension = extension; assetType = AssetDatabase.GetMainAssetTypeAtPath(path); } public void WriteToBuilder(StringBuilder builder) { if (builder.Length > 0) builder.Append('\n'); builder.Append(assetPath); builder.Append('\t'); builder.Append(extension); builder.Append('\t'); builder.Append(inResource); builder.Append('\t'); builder.Append(refByResource); builder.Append('\t'); builder.Append(refCount); } }