美术会有大量的文件资源导入,使用自动化的工具检查资源的使用情况,标记出资源引用为0的资源,用于检查无用的资源。
检查目标文件夹下的资源引用,标记出资源引用数为0的资源。
Directory.GetFiles此方法用来查找文件
采用三个参数的重载Get<wbr>Files(String, String, Search<wbr>Option)
介绍:
Returns the names of files (including their paths) that match the specified search pattern in the specified directory, using a value to determine whether to search subdirectories.
参数:
第二个参数
The search string to match against the names of files in path
. This parameter can contain a combination of valid literal path andwildcard
(* and ?) characters, but it doesn't support regular expressions.
wildcard :
In software, a wildcard character is a kind of placeholder represented by a single character, such as an asterisk (*)
, which can be interpreted as a number of literal characters or an empty string. It is often used in file searches so the full name need not be typed
使用IEnumable,代替递归的方法,来进行优化,读取文本将全部能引用的文件中的GUID读取进入一个dictionary,并计数,再对比dictionary和目标文件中的资产guid是否被引用过。时间复杂度降为N+M。
首先将读取全部文本不用后缀的方式,改用AssetDatabase.FindAssets的方式进行文件过滤。
将原本的方法进行进一步的抽象,方便编程人员进行使用方法。
将场景和其他类型文件进行整合,如果是.Unity的场景文件,直接通过GetDependencies方法取得场景全部的引用。
其他文件通过 AssetDatabase.LoadAllAssetsAtPath获取到文件的全部资产,将获得的资产 SerializedObject序列化,再遍历序列化的对象来取得索引对象属性的objectReferenceInstanceIDValue,通过GetAssetPath方法将InstanceID转换为asset路径,再通过AssetDataBase.AssetPathToGUID方法将asset路径转换为GUID存入Dictionary。
最后还是通过对比GUID的方式进行未引用资源的查找。
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace SPGF.Tools
{
public static class FindUnusedAssets
{
[MenuItem("Tools/Find Unused Assets (UI)", false, 100)]
static private void RunUI()
{
var artsPath = Path.Combine(Utils.GetArtsPath(), "Canvases");
Run(
"t:Texture t:Animation t:Animator",
new string[] {
artsPath + "/_Animations",
artsPath + "/_Textures",
artsPath + "/_BackgroundTextures",
artsPath + "/_Atlases"
},
"t:Scene t:Prefab t:Material t:Animation t:Animator",
new string[] {
artsPath
}
);
}
[MenuItem("Tools/Find Unused Assets (Efxs)", false, 101)]
static private void RunEfxs()
{
var artsPath = Path.Combine(Utils.GetArtsPath(), "Effects");
Run(
//"t:Texture t:Animation t:Animator t:Model",
"t:Texture t:Animation t:AnimatorController t:Model",
new string[] {
artsPath
},
"t:Prefab t:Material t:Animation t:AnimatorController",
new string[] {
artsPath
}
);
}
private static void Run(string srcPattern, string[] srcPaths, string dstPattern, string[] dstPaths)
{
var iterator = Match(srcPattern, srcPaths, dstPattern, dstPaths).GetEnumerator();
EditorApplication.update = delegate ()
{
if (!iterator.MoveNext())
{
EditorUtility.ClearProgressBar();
EditorApplication.update = null;
}
};
}
private static IEnumerable Match(string srcPattern, string[] srcPaths, string dstPattern, string[] dstPaths)
{
var files = AssetDatabase.FindAssets(dstPattern, dstPaths)
.Select(item => AssetDatabase.GUIDToAssetPath(item))
.ToArray();
Debug.Log("total files count : " + files.Length);
var fileGuilds = new Dictionary<string, int>();
for (var i = 0; i < files.Length; i++)
{
var file = files[i];
if (EditorUtility.DisplayCancelableProgressBar("Searching...", file, (float)i / (float)files.Length))
yield break;
var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(file);
if (sceneAsset != null)
{
foreach (var assetPath in AssetDatabase.GetDependencies(file, false))
{
var guid = AssetDatabase.AssetPathToGUID(assetPath);
var c = 0;
if (!fileGuilds.TryGetValue(guid, out c))
fileGuilds.Add(guid, 0);
fileGuilds[guid] += 1;
}
}
else
{
foreach (var obj in AssetDatabase.LoadAllAssetsAtPath(file))
{
//Change
if (obj != null)
{
SerializedObject so = new SerializedObject(obj);
var iter = so.GetIterator();
while (iter.Next(true))
{
if (iter.propertyType == SerializedPropertyType.ObjectReference && iter.objectReferenceInstanceIDValue != 0)
{
var assetPath = AssetDatabase.GetAssetPath(iter.objectReferenceInstanceIDValue);
if (!string.IsNullOrEmpty(assetPath))
{
var guid = AssetDatabase.AssetPathToGUID(assetPath);
var c = 0;
if (!fileGuilds.TryGetValue(guid, out c))
fileGuilds.Add(guid, 0);
fileGuilds[guid] += 1;
}
}
}
}
else
{
//Debug.LogError(file);
}
}
}
yield return null;
}
var guids = AssetDatabase.FindAssets(srcPattern, srcPaths);
foreach (var item in guids)
{
if (!fileGuilds.ContainsKey(item))
{
var assetPath = AssetDatabase.GUIDToAssetPath(item);
Debug.LogWarning(string.Format("Found unused asset {0}({1}).", assetPath, item), AssetDatabase.LoadAssetAtPath<Object>(assetPath));
}
}
}
}
}
网友评论