190 lines
6.5 KiB
C#
190 lines
6.5 KiB
C#
using System;
|
||
using UnityEngine;
|
||
using UnityEditor;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
/// <summary>
|
||
/// 扫描出全部资源中,非GameObject,也没有被任何GameObject或者Scene引用的资源;
|
||
/// </summary>
|
||
public class UnusedResourceToList
|
||
{
|
||
[MenuItem("ResourceTool/Scan All Assets")]
|
||
public static void Get()
|
||
{
|
||
var instance = new UnusedResourceToList();
|
||
instance.Start();
|
||
}
|
||
|
||
private List<ResourceUsageData> _assetList;
|
||
private List<string> _failAsset;
|
||
private string[] _testList;
|
||
private int _index;
|
||
protected void Start()
|
||
{
|
||
_failAsset = new List<string>();
|
||
var assetPaths = AssetDatabase.GetAllAssetPaths();
|
||
_assetList = new List<ResourceUsageData>(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;
|
||
}
|
||
/// <summary>
|
||
/// 从Scene和GameObject建立连接库
|
||
/// </summary>
|
||
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);
|
||
}
|
||
} |