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数量大幅增加,说明确实连带加载了引用资源",
"确定");
}
}
}