using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; namespace SLSUtilities.General { /// /// 一个复合布尔值类,支持多来源修改和优先级系统。 /// 可以将多个来源对布尔值的修改综合起来,由高优先级的修改决定最终结果。 /// [InlineProperty] [HideReferenceObjectPicker] public class CompoundBool { /// /// 返回当前生效优先级层级的计数。 /// [ShowInInspector] [LabelText("True Count"), LabelWidth(70)] [HorizontalGroup("Stats", Width = 100)] public int TrueCount => GetEffectiveCount(); private SortedList counts = new SortedList(); private bool isDirty = true; private bool cachedValue; /// /// 获取最终计算出的布尔值。 /// [ShowInInspector] [LabelText("Value"), LabelWidth(50)] [HorizontalGroup("Stats", Width = 100)] public bool Value { get { if (isDirty) RecalculateValue(); return cachedValue; } } /// /// 初始化 CompoundBool。 /// /// 初始值。如果为 true,将在优先级 0 初始化计数为 1。 public CompoundBool(bool initialValue = false) { if (initialValue) Modify(true, 0); } /// /// 在指定的优先级层级修改布尔值。 /// 高优先级的值会覆盖低优先级的值。 /// 如果某个非零优先级的计数变为零,将自动移除该优先级层级。 /// /// 修改意图(true 增加计数,false 减少计数)。 /// 优先级,默认为 0。数字越大优先级越高。 public void Modify(bool marker, int priority = 0) { if (counts.TryGetValue(priority, out int currentCount)) { counts[priority] = marker ? currentCount + 1 : currentCount - 1; } else { counts.Add(priority, marker ? 1 : -1); } if(priority != 0 && counts[priority] == 0) { counts.Remove(priority); } isDirty = true; } /// /// 重置所有修改,恢复到默认状态(false)。 /// public void Reset() { counts.Clear(); isDirty = true; } private void RecalculateValue() { // 从最高优先级(列表末尾)向最低优先级迭代 for (int i = counts.Count - 1; i >= 0; i--) { int count = counts.Values[i]; if (count != 0) { cachedValue = count > 0; isDirty = false; return; } } // 如果所有计数都为零或列表为空,则默认为 false cachedValue = false; isDirty = false; } private int GetEffectiveCount() { // 从最高优先级向最低优先级迭代 for (int i = counts.Count - 1; i >= 0; i--) { int count = counts.Values[i]; if (count != 0) return count; } return 0; } } }