using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; namespace AibisDream { [CreateAssetMenu(fileName = "BlockPuzzleValidator", menuName = AibisAssetMenus.BlockPuzzleValidator)] public class BlockPuzzleValidator : ScriptableObject { [Tooltip("基础条件, 不满足无法提交")] public ValidateItem[] baseConditions; public UnityEvent OnValidate = new(); /// /// 验证是否可以完成拼图 /// /// /// public ValidateResult Validate(List shapeInGrid) { var result = new ValidateResult(); var propValue = new BlockPuzzleParamValue(); // 统计每个Shape的属性值 foreach (var shape in shapeInGrid) { propValue.power += shape.BlockShapeData.blockShapeInfo.paramValue.power; propValue.noise += shape.BlockShapeData.blockShapeInfo.paramValue.noise; propValue.heat += shape.BlockShapeData.blockShapeInfo.paramValue.heat; } // 保存所有Property的值 result.propValue = propValue; // 校验基础条件 foreach (var condition in baseConditions) { int propertyValue = GetPropertyValue(propValue, condition.paramType); var itemResult = condition.Validate(propertyValue); // 保存每个条件的验证结果 result.conditionResults.Add(new PropertyValidationResult { propertyName = condition.paramType.ToString(), propertyValue = propertyValue, conditionName = condition.name, isValid = itemResult }); result.isPass = result.isPass && itemResult; } OnValidate.Invoke(result); return result; } /// /// 根据参数类型获取对应的属性值 /// /// 属性值结构 /// 参数类型 /// 属性值 private int GetPropertyValue(BlockPuzzleParamValue propValue, ParamType paramType) { return paramType switch { ParamType.Power => propValue.power, ParamType.Noise => propValue.noise, ParamType.Heat => propValue.heat, _ => 0 }; } /// /// 收集Power, Noise, Heat的阈值,并以BlockPuzzleParamValue的形式返回 /// /// 包含各参数阈值的BlockPuzzleParamValue结构 public BlockPuzzleParamValue CollectThresholds() { var thresholds = new BlockPuzzleParamValue(); if (baseConditions == null) return thresholds; // 遍历所有条件,收集每个参数类型的阈值 // 如果同一参数类型有多个条件,取第一个匹配的阈值 bool powerFound = false; bool noiseFound = false; bool heatFound = false; foreach (var condition in baseConditions) { if (!powerFound && condition.paramType == ParamType.Power) { thresholds.power = condition.threshold; powerFound = true; } else if (!noiseFound && condition.paramType == ParamType.Noise) { thresholds.noise = condition.threshold; noiseFound = true; } else if (!heatFound && condition.paramType == ParamType.Heat) { thresholds.heat = condition.threshold; heatFound = true; } // 如果所有参数类型都已找到,可以提前退出 if (powerFound && noiseFound && heatFound) break; } return thresholds; } [System.Serializable] public struct ValidateItem { [Tooltip("条件名称, 仅用于显示")] public string name; [Tooltip("要验证的属性类型")] public ParamType paramType; [Tooltip("比较类型")] public ComparisonType comparisonType; [Tooltip("阈值")] public int threshold; public bool Validate(int propertyValue) { return comparisonType switch { ComparisonType.GreaterThan => propertyValue > threshold, ComparisonType.LessThan => propertyValue < threshold, ComparisonType.GreaterThanOrEqual => propertyValue >= threshold, ComparisonType.LessThanOrEqual => propertyValue <= threshold, _ => false }; } } /// /// 参数类型枚举,用于选择要验证的属性 /// public enum ParamType { /// /// 功率 /// Power, /// /// 噪音 /// Noise, /// /// 热量 /// Heat } public enum ComparisonType { /// /// 大于阈值 /// GreaterThan, /// /// 小于阈值 /// LessThan, /// /// 大于等于阈值 /// GreaterThanOrEqual, /// /// 小于等于阈值 /// LessThanOrEqual } } public class ValidateResult { /// /// 完整的验证结果,所有基础条件都满足时为true /// public bool isPass; /// /// 所有Shape的属性值 /// public BlockPuzzleParamValue propValue; /// /// 每个条件的验证结果,包含Property的值和验证结果 /// public List conditionResults; public ValidateResult() { isPass = true; propValue = new BlockPuzzleParamValue(); conditionResults = new List(); } } [System.Serializable] public class PropertyValidationResult { /// /// 属性名称 /// public string propertyName; /// /// 属性值 /// public int propertyValue; /// /// 条件名称 /// public string conditionName; /// /// 是否通过验证 /// public bool isValid; } }