using UnityEngine; using UnityEditor; using ArtResource; using System.Diagnostics; using Debug = UnityEngine.Debug; namespace CrazyMaple.Editor { /// /// 测试工具:验证SO加载时是否会连带加载引用资源 /// /// 测试方法: /// 1. 在加载SO前后检查内存中的资源数量 /// 2. 分别测试带引用和不带引用的SO /// 3. 分析加载耗时差异 /// public class ArtResourceLoadTest : EditorWindow { [MenuItem("美术工具/性能测试工具/测试SO加载行为")] public static void ShowWindow() { GetWindow("SO加载测试"); } private void OnGUI() { GUILayout.Label("SO加载行为测试", EditorStyles.boldLabel); GUILayout.Space(10); if (GUILayout.Button("测试1: 检查SO序列化大小", GUILayout.Height(40))) { TestSerializationSize(); } GUILayout.Space(5); if (GUILayout.Button("测试2: 对比加载时间(带引用 vs 纯路径)", GUILayout.Height(40))) { TestLoadingTime(); } GUILayout.Space(5); if (GUILayout.Button("测试3: 检查内存占用(加载前后)", GUILayout.Height(40))) { TestMemoryUsage(); } GUILayout.Space(10); EditorGUILayout.HelpBox( "这些测试将帮助确定:\n" + "1. SO是否会连带加载引用资源\n" + "2. 引用字段对加载速度的影响\n" + "3. 内存占用差异", MessageType.Info); } /// /// 测试1: 检查SO序列化后的文件大小 /// private void TestSerializationSize() { Debug.Log("========== 测试1: SO序列化大小 =========="); string[] guids = AssetDatabase.FindAssets("t:ArtTableSO"); if (guids.Length == 0) { Debug.LogWarning("未找到任何ArtTableSO"); return; } foreach (var guid in guids) { string path = AssetDatabase.GUIDToAssetPath(guid); var table = AssetDatabase.LoadAssetAtPath(path); if (table != null) { // 获取文件大小 var fileInfo = new System.IO.FileInfo(path); long fileSize = fileInfo.Length; // 统计引用数量 int spriteRefCount = 0; int spineRefCount = 0; int pathCount = 0; foreach (var item in table.Items) { if (item.Sprite != null) spriteRefCount++; if (item.SpineAsset != null) spineRefCount++; if (!string.IsNullOrEmpty(item.SpritePath) || !string.IsNullOrEmpty(item.SpineAssetPath)) pathCount++; } Debug.Log($"SO: {table.TableName}\n" + $" 文件大小: {fileSize / 1024f:F2} KB\n" + $" 资源项数: {table.Items.Count}\n" + $" Sprite引用: {spriteRefCount}\n" + $" Spine引用: {spineRefCount}\n" + $" 路径字段: {pathCount}"); } } Debug.Log("========== 测试1 完成 =========="); EditorUtility.DisplayDialog("测试完成", "请查看Console日志了解SO文件大小和引用情况", "确定"); } /// /// 测试2: 对比加载时间 /// private void TestLoadingTime() { Debug.Log("========== 测试2: 加载时间对比 =========="); string[] guids = AssetDatabase.FindAssets("t:ArtTableSO"); if (guids.Length == 0) { Debug.LogWarning("未找到任何ArtTableSO"); return; } foreach (var guid in guids) { string path = AssetDatabase.GUIDToAssetPath(guid); // 卸载以确保测试准确 Resources.UnloadUnusedAssets(); System.GC.Collect(); // 测试加载时间 var sw = Stopwatch.StartNew(); var table = AssetDatabase.LoadAssetAtPath(path); sw.Stop(); if (table != null) { // 统计引用情况 int refCount = 0; foreach (var item in table.Items) { if (item.Sprite != null || item.SpineAsset != null) refCount++; } Debug.Log($"SO: {table.TableName}\n" + $" 加载耗时: {sw.Elapsed.TotalMilliseconds:F2} ms\n" + $" 资源项数: {table.Items.Count}\n" + $" 含引用项: {refCount}\n" + $" 平均耗时: {sw.Elapsed.TotalMilliseconds / table.Items.Count:F3} ms/项"); // 尝试访问一个引用,看看是否触发额外加载 if (table.Items.Count > 0 && table.Items[0].Sprite != null) { var sw2 = Stopwatch.StartNew(); var sprite = table.Items[0].Sprite; // 访问引用 var name = sprite.name; // 访问属性 sw2.Stop(); Debug.Log($" 访问第1个Sprite引用: {sw2.Elapsed.TotalMilliseconds:F2} ms"); } } } Debug.Log("========== 测试2 完成 =========="); EditorUtility.DisplayDialog("测试完成", "请查看Console日志了解加载时间差异", "确定"); } /// /// 测试3: 检查内存占用 /// private void TestMemoryUsage() { Debug.Log("========== 测试3: 内存占用测试 =========="); // 清理内存 Resources.UnloadUnusedAssets(); System.GC.Collect(); long memBefore = System.GC.GetTotalMemory(true); int textureBefore = Resources.FindObjectsOfTypeAll().Length; int spriteBefore = Resources.FindObjectsOfTypeAll().Length; Debug.Log($"加载前:\n" + $" 托管内存: {memBefore / 1024f / 1024f:F2} MB\n" + $" Texture2D数量: {textureBefore}\n" + $" Sprite数量: {spriteBefore}"); // 加载所有SO string[] guids = AssetDatabase.FindAssets("t:ArtTableSO"); var tables = new System.Collections.Generic.List(); foreach (var guid in guids) { string path = AssetDatabase.GUIDToAssetPath(guid); var table = AssetDatabase.LoadAssetAtPath(path); if (table != null) { tables.Add(table); } } long memAfter = System.GC.GetTotalMemory(false); int textureAfter = Resources.FindObjectsOfTypeAll().Length; int spriteAfter = Resources.FindObjectsOfTypeAll().Length; Debug.Log($"加载后:\n" + $" 托管内存: {memAfter / 1024f / 1024f:F2} MB (+{(memAfter - memBefore) / 1024f / 1024f:F2} MB)\n" + $" Texture2D数量: {textureAfter} (+{textureAfter - textureBefore})\n" + $" Sprite数量: {spriteAfter} (+{spriteAfter - spriteBefore})"); Debug.Log($"共加载 {tables.Count} 个SO"); Debug.Log("========== 测试3 完成 =========="); EditorUtility.DisplayDialog( "测试完成", $"内存增加: {(memAfter - memBefore) / 1024f / 1024f:F2} MB\n" + $"Texture2D增加: {textureAfter - textureBefore}\n" + $"Sprite增加: {spriteAfter - spriteBefore}\n\n" + $"如果纹理/Sprite数量大幅增加,说明确实连带加载了引用资源", "确定"); } } }