基于回合制的战斗系统动作取决于动作延迟值

时间:2017-10-30 20:48:08

标签: c# unity3d

我在Unity中建立了一个有效的回合制战斗系统,虽然我现在可以循环每个玩家/敌人并选择他们的动作,但我的设计选择之一就是在每个动作发生时都会有几秒钟的延迟。这意味着即使playerA在playerB之前做出选择,如果玩家B的选择有较短的延迟,那么它应该先被处理。

现在,如果玩家A选择一个应该需要10秒施法的咒语但是玩家B选择进行物理攻击(延迟为2秒),他必须等到玩家在转弯之前施放他的咒语。

ATB的工作方式是我有一个Actors列表,这个类包含所采取行动类型的所有信息,是谁以及它的目标。

我有这段代码:

public class BattleStateMachine : MonoBehaviour {

    public enum BattleStates {
        INITIALIZE,
        WAITING,
        PROCESS_ACTION,
        IDLE,
        CHECK_IF_ALIVE,
        WON,
        LOST
    }

    public BattleStates currState;

    public List<Actor> actors = new List<Actor>();      //List of actors, which contains the details of the action taken by the battler

    public List<GameObject> heroesToManage = new List<GameObject>();

    // Update is called once per frame
    void Update() {

        switch(currState) {

            case BattleStates.INITIALIZE: {
                    currState = BattleStates.WAITING;
                    break;
                }

            case BattleStates.WAITING: {
                    if(actors.Count > 0)
                        currState = BattleStates.PROCESS_ACTION;
                    break;
                }

            case BattleStates.PROCESS_ACTION: {
                    HeroStateMachine hsm = actors[0].Origin.GetComponent<HeroStateMachine>();
                    hsm.target = actors[0].Target;
                    hsm.currState = HeroStateMachine.TurnStates.ACTION;
                    break;
                }
        }
    }
}

public class Actor
{
    public GameObject Origin;
    public GameObject Target;

    public BaseAction ChosenAction;
}

public class HeroStateMachine : MonoBehaviour {

    public BattleStateMachine bsm;

    public enum TurnStates {
        WAITING,
        ADDTOLIST,
        IDLE,
        ACTION,
        DEAD
    }

    public TurnStates currState;

    void Update () {

        switch(currState) {

            case TurnStates.WAITING: {
                    UpdateATBGauge();
                    break;
                }

            case TurnStates.ADDTOLIST: {
                    bsm.heroesToManage.Add(this.gameObject);
                    currState = TurnStates.IDLE;

                    break;
                }

            case TurnStates.IDLE: {
                    break;
                }

            case TurnStates.ACTION: {
                    StartCoroutine(TimeForAction());
                    break;
                }
        }
    }

    private IEnumerator TimeForAction() {

        if(actionStarted)
            yield break;

        actionStarted = true;

        yield return new WaitForSeconds(bsm.actors[0].ChosenAction.ActionDelay);

        DoDamage();

        bsm.actors.RemoveAt(0);
        bsm.currState = BattleStateMachine.BattleStates.WAITING;
        actionStarted = false;

        statsPanel.progressGauge.value = 0f;
        currState = TurnStates.WAITING;
    }
}

为了解释它的工作方式,我将尝试一个例子。

HeroStateMachine的ATB测量仪被填充,它被添加到BattleStateMachine heroesToManage列表中。然后我们选择在EnemyA上施放火球咒语。 Actor类的一个实例以英雄为原点,EnemyA为目标,咒语&#34; Fireball&#34;作为选择的攻击。实例将添加到actor列表中。假设它是演员列表中Actor的第一个实例,我们启动Coroutine,所以我们等待3.5秒(Fireball法术的延迟。一旦时间过去,我们对EnemyA造成伤害,删除第一个实例列表中的Actor和ATB Gauge将重置。

现在,为了解决问题并首先处理演员列表中最快的动作,我想到不断监视演员列表并重新排序,以便最接近完成总是先结束。但是,我担心这会对CPU功耗造成极大的损失,而且,我需要为每个演员保留一个计时器,可能会占用更多的CPU周期......

有没有其他方法可以做我想要的,或者每次添加新Actor时都会不断重新排序列表真的是唯一的方法吗?

0 个答案:

没有答案