我在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时都会不断重新排序列表真的是唯一的方法吗?