You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何全局修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:06:00