如何全局修改BattleState枚举值 让所有引用脚本同步生效
实现方案
方案1:单例管理器+事件监听(推荐新手使用,逻辑更清晰)
你可以把BattleState枚举和状态管理逻辑放到一个统一的战斗管理器类里,示例代码如下:
// 战斗状态枚举 public enum BattleState { START, PLAYERMAINPHASE, PLAYERBATTLEPHASE, PLAYERENCORESTEP, ENEMYTURN, WON, LOST } public class BattleManager : MonoBehaviour { // 全局可访问的单例实例 public static BattleManager Instance { get; private set; } // 状态变更事件,所有需要监听状态变化的脚本都可以订阅该事件 public event System.Action<BattleState> OnBattleStateChanged; // 私有存储当前状态,禁止外部直接修改 private BattleState _currentBattleState; // 对外暴露的只读状态属性 public BattleState CurrentBattleState { get => _currentBattleState; private set { // 只有状态实际变更时才触发事件,避免多余调用 if (_currentBattleState == value) return; _currentBattleState = value; OnBattleStateChanged?.Invoke(_currentBattleState); } } private void Awake() { // 单例初始化逻辑 if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; // 如果需要跨场景保留管理器,可开启下面的注释 // DontDestroyOnLoad(gameObject); } // 统一的状态修改入口,所有要改状态的逻辑都调用该方法 public void ChangeBattleState(BattleState newState) { CurrentBattleState = newState; } }
使用方式
- 修改状态:直接调用
BattleManager.Instance.ChangeBattleState(BattleState.PLAYERMAINPHASE)即可 - 监听状态变化的脚本需要在初始化时订阅事件,销毁时取消订阅,避免内存泄漏,示例代码:
public class YourOtherScript : MonoBehaviour { private void OnEnable() { // 订阅状态变更事件 BattleManager.Instance.OnBattleStateChanged += OnBattleStateUpdate; } private void OnDisable() { // 必须取消订阅,否则对象销毁后会触发空引用异常 BattleManager.Instance.OnBattleStateChanged -= OnBattleStateUpdate; } // 状态变化时自动触发该方法,参数为最新的战斗状态 private void OnBattleStateUpdate(BattleState newState) { // 这里写对应状态的处理逻辑即可 switch (newState) { case BattleState.ENEMYTURN: Debug.Log("进入敌人回合"); break; case BattleState.WON: Debug.Log("玩家战斗胜利"); break; // 其他状态逻辑自行补充 } } }
方案2:静态事件实现(不需要挂载MonoBehaviour)
如果你的战斗管理逻辑不需要继承MonoBehaviour,可以用更轻量的静态事件实现:
public enum BattleState { START, PLAYERMAINPHASE, PLAYERBATTLEPHASE, PLAYERENCORESTEP, ENEMYTURN, WON, LOST } public static class BattleStateUtility { public static event System.Action<BattleState> OnBattleStateChanged; private static BattleState _currentState; public static BattleState CurrentState { get => _currentState; set { if (_currentState == value) return; _currentState = value; OnBattleStateChanged?.Invoke(_currentState); } } }
使用方式
- 修改状态:
BattleStateUtility.CurrentState = BattleState.ENEMYTURN; - 订阅逻辑和方案1一致,只需把事件来源替换为
BattleStateUtility.OnBattleStateChanged即可
注意事项
- 订阅事件后必须在对象销毁/禁用时取消订阅,否则会导致内存泄漏或者空引用报错
- 所有状态修改都走统一入口,不要在外部直接修改状态存储变量,才能保证事件正常触发
内容的提问来源于stack exchange,提问作者CodingNewbie
相关产品推荐
相关产品推荐

