Unity中利用协程控制回合制游戏的战斗逻辑

最近做受难日的战斗系统这一块。游戏的战斗模块偏回合制(虽然也与传统的回合制有所不同),玩家回合玩家选择相应的攻击方式后完成攻击结算,进入敌人回合。敌人回合玩家需要选择相应的防御方式,然后进行攻击结算,重新进入玩家回合。这也构成了一个基本的战斗循环。

由于并不是即时制的战斗,所以如果在Update中更新游戏战斗循环显得并不怎么合适,这里我们可以用协程的方式来控制游戏循环。

关于协程(Coroutine)的基本知识我在之前的文章中提到过,详见https://lc1995.github.io/2017/11/22/Understand%20Coroutine%20in%20Unity/

对于回合制战斗,我们假设场景中只有玩家和敌人两个单位,分别行动一回合,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void StartBattle(Character player, Character enemy){
StartCoroutine(Battle(player, enemy));
}

public IEnumerator Battle(Character player, Character enemy){
while(true){
yield return StartCoroutine(Turn(player));

if(CheckBattleOver(player, enemy))
break;

yield return StartCoroutine(Turn(enemy));

if(CheckBattleOver(player, enemy))
break;
}
}

在上述代码中,当程序遇到yield return StartCoroutine(Turn(player))时,会返回并一直到对应的协程(这里是Turn)结束后才重新执行。通过这样的方式,我们便可以实现回合制战斗中回合的有序性。

同样,如果在Turn中涉及到玩家输入,动画的控制或者位置上的移动(等待用户输入,玩家移动到敌人前面,进行攻击动画,玩家回到原来的位置),也可以通过协程的方式来控制它们的连续性,代码如下:

1
2
3
4
5
6
public IEnumerator Turn(Character ch){
yield return new WaitUntil(() => PlayerInput != null);
yield return new StartCoroutine(PlayerMove(enemy.position));
yield return new StartCoroutine(PlayerAttack(enemy));
yield return new StartCoroutine(PlayerMove(player.originalPosition));
}

再扩展一点,如果此时是多单位进行战斗,每个单位的速度不同,速度高的先攻击。我们可以利用的同样的方式,先对所有单位按速度排序,之后每次取出一个单位进行攻击并结算即可。本质上没有太大的区别。

个人理解,如有问题欢迎指出。