04-06-YooAsset源码-Unity调试与扫描工具
源码-调试与诊断工具
篇章:04-源码深度-编辑器模块
阅读时间:约 25 分钟
前置知识:了解清单与报告
一、引言
本章将深入解析 YooAsset 调试与诊断工具的源码实现。YooAsset 提供了多个调试和诊断工具,包括 AssetBundle Debugger、Asset Scanner、Runtime Debugger 等。这些工具帮助开发者诊断资源管理问题、分析 Bundle 结构、排查性能瓶颈。
本章将从源码层面深入解析这些调试诊断工具的设计和实现。
二、AssetBundle Debugger
2.1 Debugger 的作用
AssetBundle Debugger 是 YooAsset 的核心调试工具:
功能:
- 查看 Bundle 列表
- 查看 Bundle 详细信息
- 查看 Bundle 之间的依赖关系
- 查看资源地址映射
- 模拟加载资源
使用场景:
- 构建后查看 Bundle 结构
- 分析 Bundle 依赖问题
- 优化资源打包
- 排查资源加载问题
2.2 Debugger 的实现
public class AssetBundleDebugger
{
private PackageManifest _manifest;
public void LoadManifest(string manifestPath)
{
_manifest = PackageManifest.LoadFromFile(manifestPath);
}
public List<PackageBundle> GetAllBundles()
{
return _manifest?.BundleList.Bundles;
}
public PackageBundle GetBundle(string bundleName)
{
return _manifest?.BundleList.Bundles.FirstOrDefault(b => b.BundleName == bundleName);
}
public List<PackageBundle> GetBundleDependencies(string bundleName)
{
var bundle = GetBundle(bundleName);
if (bundle == null) return new List<PackageBundle>();
return bundle.DependIDs
.Select(id => _manifest.BundleList.Bundles.FirstOrDefault(b => b.BundleID == id))
.Where(b => b != null)
.ToList();
}
public List<PackageBundle> GetBundleDependents(string bundleName)
{
var bundle = GetBundle(bundleName);
if (bundle == null) return new List<PackageBundle>();
return _manifest.BundleList.Bundles
.Where(b => b.DependIDs.Contains(bundle.BundleID))
.ToList();
}
}
加载 Manifest 详解:
Debugger 需要先加载 PackageManifest,然后基于 PackageManifest 提供调试功能。
获取 Bundle 列表详解:
获取所有 Bundle 的列表,并显示 Bundle 的详细信息。
获取依赖关系详解:
根据 Bundle 的依赖关系,获取依赖的 Bundle 和被依赖的 Bundle。
2.3 Debugger Window
AssetBundleDebuggerWindow 是 Debugger 的 UI 窗口:
public class AssetBundleDebuggerWindow : EditorWindow
{
[MenuItem("YooAsset/AssetBundle Debugger")]
public static void Open()
{
AssetBundleDebuggerWindow window = GetWindow<AssetBundleDebuggerWindow>();
window.titleContent = new GUIContent("AssetBundle Debugger");
window.Show();
}
private void OnGUI()
{
// 绘制 UI
DrawToolbar();
DrawBundleList();
DrawBundleDetails();
}
}
打开窗口详解:
通过菜单项 YooAsset/AssetBundle Debugger 打开调试窗口。
绘制 UI 详解:
窗口主要分为三个区域:工具栏、Bundle 列表、Bundle 详情。
工具栏详解:
工具栏包括加载 Manifest、刷新、搜索等功能。
Bundle 列表详解:
Bundle 列表显示所有 Bundle 的概要信息,包括名称、大小、Hash 等。
Bundle 详情详解:
Bundle 详情显示选中 Bundle 的详细信息,包括资源列表、依赖关系等。
2.4 Debugger 的高级功能
模拟加载:
public class AssetBundleDebugger
{
public AssetBundle SimulateLoadBundle(string bundleName)
{
// 模拟加载 Bundle,不实际加载文件
return null;
}
}
模拟加载功能允许开发者在不实际加载资源的情况下模拟加载流程,便于调试。
依赖分析:
public class AssetBundleDebugger
{
public DependencyGraph AnalyzeDependencies()
{
var graph = new DependencyGraph();
foreach (var bundle in _manifest.BundleList.Bundles)
{
graph.AddNode(bundle.BundleName);
foreach (var depId in bundle.DependIDs)
{
var depBundle = _manifest.BundleList.Bundles.FirstOrDefault(b => b.BundleID == depId);
if (depBundle != null)
{
graph.AddEdge(bundle.BundleName, depBundle.BundleName);
}
}
}
return graph;
}
}
依赖分析功能分析所有 Bundle 的依赖关系,生成依赖图。
三、Asset Scanner
3.1 Scanner 的作用
Asset Scanner 是 YooAsset 的资源扫描器:
功能:
- 扫描项目中所有资源
- 分析资源依赖关系
- 检测未使用的资源
- 检测资源冗余
- 检测大文件
使用场景:
- 定期清理未使用资源
- 优化资源打包
- 减小包体大小
- 提高资源管理效率
3.2 Scanner 的实现
public class AssetScanner
{
public ScanReport Scan(string folderPath)
{
ScanReport report = new ScanReport();
// 1. 扫描所有资源
var assets = GetAllAssets(folderPath);
// 2. 分析每个资源
foreach (var asset in assets)
{
var assetInfo = new AssetInfo();
assetInfo.Path = asset;
assetInfo.Dependencies = AssetDatabase.GetDependencies(asset, true).ToList();
assetInfo.FileSize = new FileInfo(asset).Length;
report.Assets.Add(assetInfo);
}
// 3. 检测未使用的资源
report.UnusedAssets = DetectUnusedAssets(report.Assets);
// 4. 检测冗余资源
report.RedundantAssets = DetectRedundantAssets(report.Assets);
// 5. 检测大文件
report.LargeAssets = DetectLargeAssets(report.Assets, 1024 * 1024);
return report;
}
private List<string> GetAllAssets(string folderPath)
{
var guids = AssetDatabase.FindAssets(string.Empty, new[] { folderPath });
return guids.Select(AssetDatabase.GUIDToAssetPath).ToList();
}
}
扫描资源详解:
使用 AssetDatabase.FindAssets 扫描指定文件夹下的所有资源。
分析资源详解:
为每个资源创建 AssetInfo,包含资源路径、依赖关系、文件大小等。
检测未使用资源详解:
使用反射 API 扫描所有引用关系,找出未被引用的资源。
检测冗余资源详解:
找出被多次打包的资源,提示开发者提取为共享资源。
检测大文件详解:
找出超过指定大小的资源,提示开发者优化或压缩。
3.3 Scanner Window
AssetScannerWindow 是 Scanner 的 UI 窗口:
public class AssetScannerWindow : EditorWindow
{
[MenuItem("YooAsset/Asset Scanner")]
public static void Open()
{
AssetScannerWindow window = GetWindow<AssetScannerWindow>();
window.titleContent = new GUIContent("Asset Scanner");
window.Show();
}
private void OnGUI()
{
DrawFolderSelection();
DrawScanOptions();
DrawScanButton();
DrawScanResults();
}
}
打开窗口详解:
通过菜单项 YooAsset/Asset Scanner 打开扫描窗口。
绘制 UI 详解:
窗口包括文件夹选择、扫描选项、扫描按钮、扫描结果等区域。
扫描选项详解:
扫描选项包括检测未使用资源、检测冗余资源、检测大文件等。
3.4 扫描结果展示
扫描结果通过 ScanReport 展示:
public class ScanReport
{
public List<AssetInfo> Assets = new List<AssetInfo>();
public List<string> UnusedAssets = new List<string>();
public List<string> RedundantAssets = new List<string>();
public List<string> LargeAssets = new List<string>();
public ScanStatistics Statistics = new ScanStatistics();
}
public class ScanStatistics
{
public int TotalAssetCount;
public long TotalFileSize;
public int UnusedAssetCount;
public long UnusedFileSize;
public int RedundantAssetCount;
public long RedundantFileSize;
}
统计信息详解:
统计信息包括总资源数、总文件大小、未使用资源数、未使用文件大小等。
未使用资源详解:
未使用资源列表显示未被引用的资源。
冗余资源详解:
冗余资源列表显示被多次打包的资源。
大文件详解:
大文件列表显示超过指定大小的资源。
四、Runtime Debugger
4.1 Runtime Debugger 的作用
Runtime Debugger 是 YooAsset 的运行时调试器:
功能:
- 查看运行时已加载的 Bundle
- 查看运行时已加载的资源
- 查看运行时缓存信息
- 查看运行时下载信息
- 监控资源加载性能
使用场景:
- 运行时调试
- 性能分析
- 内存分析
- 问题排查
4.2 Runtime Debugger 的实现
Runtime Debugger 通过 Runtime 端的接口实现:
public class RuntimeDebugger
{
public static DebugInfo GetDebugInfo(ResourcePackage package)
{
DebugInfo info = new DebugInfo();
// 1. 获取 Provider 信息
var providers = package.ResourceManager.ProviderCache;
foreach (var kvp in providers)
{
info.LoadedProviders.Add(CreateProviderInfo(kvp.Value));
}
// 2. 获取 Bundle 信息
var bundleLoaders = package.ResourceManager.BundleLoaders;
foreach (var kvp in bundleLoaders)
{
info.LoadedBundles.Add(CreateBundleInfo(kvp.Value));
}
// 3. 获取缓存信息
info.CacheInfo = package.CacheSystem.GetDebugInfo();
// 4. 获取下载信息
info.DownloadInfo = package.DownloadManager.GetDebugInfo();
return info;
}
}
Provider 信息详解:
获取所有已加载的 Provider 信息,包括 Provider 状态、引用计数、加载进度等。
Bundle 信息详解:
获取所有已加载的 Bundle 信息,包括 Bundle 状态、文件大小、引用计数等。
缓存信息详解:
获取缓存系统的信息,包括缓存文件、缓存大小、缓存命中率等。
下载信息详解:
获取下载管理器的信息,包括下载任务、下载进度、下载速度等。
4.3 Runtime Debugger Window
RuntimeDebuggerWindow 是 Runtime Debugger 的 UI 窗口:
public class RuntimeDebuggerWindow : EditorWindow
{
[MenuItem("YooAsset/Runtime Debugger")]
public static void Open()
{
RuntimeDebuggerWindow window = GetWindow<RuntimeDebuggerWindow>();
window.titleContent = new GUIContent("Runtime Debugger");
window.Show();
}
private void OnGUI()
{
DrawPackageSelection();
DrawProviderList();
DrawBundleList();
DrawCacheInfo();
DrawDownloadInfo();
}
}
打开窗口详解:
通过菜单项 YooAsset/Runtime Debugger 打开运行时调试窗口。
绘制 UI 详解:
窗口包括 Package 选择、Provider 列表、Bundle 列表、缓存信息、下载信息等。
4.4 实时监控
Runtime Debugger 支持实时监控:
public class RuntimeDebuggerWindow
{
private void OnEnable()
{
// 启动定时刷新
EditorApplication.update += OnEditorUpdate;
}
private void OnDisable()
{
EditorApplication.update -= OnEditorUpdate;
}
private void OnEditorUpdate()
{
if (EditorApplication.timeSinceStartup - _lastUpdateTime > _refreshInterval)
{
Repaint();
_lastUpdateTime = EditorApplication.timeSinceStartup;
}
}
}
定时刷新详解:
使用 EditorApplication.update 定时刷新窗口,显示最新的运行时信息。
刷新间隔详解:
刷新间隔默认为 1 秒,可根据需要调整。
五、性能分析工具
5.1 性能分析的重要性
性能分析是调试诊断的重要部分:
- 找出资源加载的性能瓶颈
- 优化资源加载流程
- 提高游戏性能
5.2 性能分析的实现
public class PerformanceProfiler
{
private Dictionary<string, List<float>> _loadTimes = new Dictionary<string, List<float>>();
public void RecordLoadTime(string assetPath, float loadTime)
{
if (!_loadTimes.ContainsKey(assetPath))
_loadTimes[assetPath] = new List<float>();
_loadTimes[assetPath].Add(loadTime);
}
public PerformanceReport GenerateReport()
{
var report = new PerformanceReport();
foreach (var kvp in _loadTimes)
{
var stats = new LoadTimeStats();
stats.AssetPath = kvp.Key;
stats.AverageLoadTime = kvp.Value.Average();
stats.MaxLoadTime = kvp.Value.Max();
stats.MinLoadTime = kvp.Value.Min();
stats.LoadCount = kvp.Value.Count;
report.LoadTimeStats.Add(stats);
}
// 按平均加载时间排序
report.LoadTimeStats = report.LoadTimeStats
.OrderByDescending(s => s.AverageLoadTime)
.ToList();
return report;
}
}
加载时间记录详解:
记录每个资源的加载时间,统计平均、最大、最小加载时间。
性能报告生成详解:
生成性能报告,按平均加载时间排序,便于找出加载慢的资源。
5.3 Unity Profiler 集成
YooAsset 集成了 Unity Profiler:
public class AssetProfiler
{
public static void BeginSample(string name)
{
UnityEngine.Profiling.Profiler.BeginSample(name);
}
public static void EndSample()
{
UnityEngine.Profiling.Profiler.EndSample();
}
}
Profiler 详解:
使用 Unity 的 Profiler API 进行性能采样。
自定义 Profiler 详解:
开发者可以自定义 Profiler 标签,便于在 Unity Profiler 中识别 YooAsset 的耗时。
5.4 Memory Profiler 集成
YooAsset 支持 Memory Profiler 集成:
public class MemoryProfiler
{
public static long GetMemoryUsage()
{
return UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong();
}
public static long GetBundleMemoryUsage()
{
long total = 0;
// 累计所有 Bundle 的内存使用
return total;
}
}
内存使用详解:
通过 Unity Profiler API 获取内存使用情况。
Bundle 内存详解:
累计所有已加载 Bundle 的内存使用。
六、总结
本章深入解析了 YooAsset 调试与诊断工具的源码实现,包括:
- AssetBundle Debugger:查看 Bundle 信息、分析依赖关系
- Asset Scanner:扫描资源、检测未使用资源、检测冗余资源
- Runtime Debugger:查看运行时信息、实时监控
- 性能分析工具:性能采样、Profiler 集成、Memory Profiler 集成
通过这些调试诊断工具,开发者可以方便地诊断和解决 YooAsset 使用过程中的问题。
更多推荐

所有评论(0)