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 使用过程中的问题。
上一篇:清单与报告
下一篇:运行时入口与初始化
