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

Unity回合制开发:玩家动作管理与冷却系统实现疑问

回合制技能冷却+TurnManager落地实现方案

核心逻辑拆分

不要一开始就把所有逻辑塞到协程里,先把职责拆干净,避免后续改不动:

  • TurnManager只负责控制回合流转、在固定节点发全局事件,不碰具体技能、冷却的逻辑
  • Action(技能对象)只负责管自己的冷却、效果、绑定按钮状态,不主动查询回合状态
  • 单位类只负责持有自己的技能列表,供UI层读取生成按钮

1. TurnManager最简实现

先定义回合阶段枚举,不要只写敌我回合,加一个专门的回合结算节点:

public enum TurnPhase
{
    AllyTurn,
    EnemyTurn,
    RoundSettle // 整轮结束,结算冷却、buff、持续伤害的节点
}

用全局事件做解耦,不要把冷却更新逻辑硬写在TurnManager里,后续加新功能不用改核心流转代码:

public class TurnManager : MonoBehaviour
{
    public static TurnManager Instance { get; private set; }
    public TurnPhase CurrentPhase { get; private set; }
    // 全局回合结束事件,所有需要跟着回合结算的逻辑都注册这个事件
    public static event Action OnRoundSettle;

    void Awake() => Instance = this;

    void Start() => StartCoroutine(TurnMainLoop());

    IEnumerator TurnMainLoop()
    {
        while (true)
        {
            // 友方行动阶段:等待玩家完成所有操作
            CurrentPhase = TurnPhase.AllyTurn;
            yield return WaitForAllAllyActionFinish();

            // 敌方行动阶段:执行AI逻辑
            CurrentPhase = TurnPhase.EnemyTurn;
            yield return RunAllEnemyAction();

            // 整轮结算:触发所有注册的结算逻辑
            CurrentPhase = TurnPhase.RoundSettle;
            OnRoundSettle?.Invoke();
            
            yield return new WaitForEndOfFrame();
        }
    }

    // 下面两个方法根据你的输入逻辑、AI逻辑补就行
    IEnumerator WaitForAllAllyActionFinish() { /* 等待玩家操作逻辑 */ yield break; }
    IEnumerator RunAllEnemyAction() { /* 敌方AI执行逻辑 */ yield break; }
}

2. 技能冷却逻辑对接

你的初始设计(回合结束冷却-1、放技能锁按钮)完全正确,只要对接全局事件就行,不要在技能自己的协程里做倒计时:

public class Action : MonoBehaviour
{
    public int maxCooldown;
    public int currentCooldown;
    public Button bindButton; // 你绑定的UI按钮

    void OnEnable()
    {
        // 注册全局结算事件
        TurnManager.OnRoundSettle += UpdateCooldown;
        bindButton.onClick.AddListener(() => StartCoroutine(TriggerSkill()));
    }

    void OnDisable()
    {
        // 一定要注销事件,避免空引用和内存泄漏
        TurnManager.OnRoundSettle -= UpdateCooldown;
        bindButton.onClick.RemoveAllListeners();
    }

    IEnumerator TriggerSkill()
    {
        // 放技能的时候直接锁按钮、设冷却
        bindButton.interactable = false;
        currentCooldown = maxCooldown;
        
        // 这里写你技能的实际效果、演出逻辑
        yield return RunSkillLogic();
    }

    void UpdateCooldown()
    {
        if (currentCooldown <= 0) return;
        
        currentCooldown--;
        // 冷却归零自动解锁按钮
        if (currentCooldown == 0) bindButton.interactable = true;
    }

    IEnumerator RunSkillLogic() { /* 技能效果逻辑 */ yield break; }
}

3. 单位技能列表实现

你计划给每个单位加List<Action>类型的动作集合的方案完全可行,UI层在选中对应单位的时候,直接读取这个列表动态生成按钮、绑定事件即可,不需要额外写冗余逻辑。


避坑提示

  • 不要用现实时间计时做回合制冷却,所有冷却跟着回合结算节点走,避免不同协程计时不同步的bug
  • 不要给TurnManager加太多无关逻辑,它只做流转和事件分发,技能、buff、伤害逻辑都放到对应类里处理,后续扩展不会乱
  • 按钮状态直接和冷却值绑定,不要单独维护按钮的状态变量,避免出现冷却好了按钮没解锁的不同步问题

内容的提问来源于stack exchange,提问作者Pablo Gasamans Losada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:12:24