最快的Unity查找资源被依赖的方式
在要Unity Editor下查找一个资源,是否被其它预制(prefab)引用,AssetDatabase并没有给出现成的API,AssetDatabase只能查找一个游戏对象依赖了哪些资源,我们可以在启动的时候,使用AssetDatabase对每个资源建议反向索引,再进行查找,但是建议反向索引的过程还是比较耗时的,项目越大,资源越多,耗时越久。
这样的方式虽然能达到查找资源被依赖的目的,但是还不够高效,下面我们讲一下,在Mac系统下,使用系统索引的方式,快速进行资源被依赖的方法,可以在1秒内,找到资源的被依赖对象,因为Mac系统已经为文件建立好了索引,所以可以直接使用,以下是已经集成好的代码工具,可以拷贝到项目里直接使用,上代码:
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
public class FindProject
{
#if UNITY_EDITOR_OSX
private static string _curFileName;
private static readonly List<string> References = new List<string>();
private static bool _canOutResult;
private static string _selectedAssetPath;
[MenuItem("Assets/Find References In Project", false, 2000)]
private static void FindProjectReferences()
{
var appDataPath = Application.dataPath;
_selectedAssetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
_curFileName = Path.GetFileName(_selectedAssetPath);
var guid = AssetDatabase.AssetPathToGUID(_selectedAssetPath);
var psi = new System.Diagnostics.ProcessStartInfo
{
WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized,
FileName = "/usr/bin/mdfind",
Arguments = "-onlyin " + Application.dataPath + " " + guid,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
EditorApplication.update += OnUpdate;
var process = new System.Diagnostics.Process();
process.StartInfo = psi;
process.OutputDataReceived += (sender, e) =>
{
if (string.IsNullOrEmpty(e.Data))
{
_canOutResult = true;
}
else
{
var fileName = Path.GetFileName(e.Data);
if (fileName.Contains(_curFileName))
{
return;
}
var relativePath = "Assets" + e.Data.Replace(appDataPath, "");
References.Add(relativePath);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (string.IsNullOrEmpty(e.Data))
return;
// output += "Error: " + e.Data + "\n";
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
private static void OnUpdate()
{
if (!_canOutResult) return;
_canOutResult = false;
var rawObj = AssetDatabase.LoadAssetAtPath<Object>(_selectedAssetPath);
Debug.Log($"<color=aqua><b>{References.Count}</b></color> 个对象引用了 <color=fuchsia><b>{_curFileName}</b></color>", rawObj);
foreach (var file in References)
{
var findObj = AssetDatabase.LoadAssetAtPath<Object>(file);
Debug.Log( $"<color=lime>引用者:</color> <color=yellow>{file}</color>", findObj);
}
}
#endif
}