Files
JJBB/Assets/Editor/Scripts/UnusedResourceToList.cs

190 lines
6.5 KiB
C#
Raw Permalink Normal View History

2024-08-23 15:49:34 +08:00
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);
}
}