Files
zeling_v2/Assets/Scripts/Editor/Validation/SOValidationRunner.cs
2026-05-12 15:34:08 +08:00

79 lines
2.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace BaseGames.Editor
{
/// <summary>
/// 扫描项目中所有实现 <see cref="BaseGames.Core.IValidatable"/> 接口的 ScriptableObject
/// 调用 Validate() 并在 Console 报告验证结果。同时作为构建前处理器,发现错误时中止构建。
///
/// 菜单Tools/Validate All ScriptableObjects
/// Build 回调顺序 = 1在 AddressKeyValidator callbackOrder = 0 之后执行)
/// </summary>
public class SOValidationRunner : IPreprocessBuildWithReport
{
public int callbackOrder => 1;
public void OnPreprocessBuild(BuildReport report)
{
var (errors, warnings) = RunAll();
foreach (var w in warnings)
Debug.LogWarning(w);
if (errors.Count > 0)
throw new BuildFailedException(
$"[SOValidationRunner] {errors.Count} 处 SO 数据错误,构建中止:\n"
+ string.Join("\n", errors));
}
[MenuItem("Tools/Validate All ScriptableObjects")]
public static void ValidateMenu()
{
var (errors, warnings) = RunAll();
if (errors.Count == 0 && warnings.Count == 0)
{
Debug.Log("[SOValidationRunner] ✅ 所有 SO 数据均合法。");
return;
}
foreach (var w in warnings) Debug.LogWarning(w);
foreach (var e in errors) Debug.LogError(e);
Debug.Log($"[SOValidationRunner] 校验完成:{errors.Count} 错误,{warnings.Count} 警告。");
}
// ── Internal ──────────────────────────────────────────────────────
private static (List<string> errors, List<string> warnings) RunAll()
{
var errors = new List<string>();
var warnings = new List<string>();
var guids = AssetDatabase.FindAssets("t:ScriptableObject");
foreach (var guid in guids)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var so = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path);
if (so is BaseGames.Core.IValidatable validatable)
{
foreach (var result in validatable.Validate())
{
if (result.Severity == BaseGames.Core.ValidationSeverity.Error)
errors.Add($"\u274c {result.Message} ({path})");
else
warnings.Add($"\u26a0\ufe0f {result.Message} ({path})");
}
}
}
return (errors, warnings);
}
}
}