实现行动轮换的基本方式
由女巫项目探究而来的优化版本。(框架)
看上图,要求实现熊大,熊二,熊三按照顺序执行行动。
using System.Collections;
using UnityEngine;
public class BattleUnit : MonoBehaviour
{
public new string name;
public IEnumerator Action()
{
print(name + "行动!");
yield return new WaitForSeconds(2f);
}
}
上面是挂载在每头熊上的脚本,用来管理每个熊的不同行为。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BattleManager : MonoBehaviour
{
public List<GameObject> UnitList;
private IEnumerator Start()
{
//要用 yield return 语句等待携程,首先后面得是个协程,而不是IEnumerator类型的变量,目前不清楚Unity底层是怎么实现Coroutine的
//以下3种方式均能实现按列表中顺序执行对应的Action()
for (int i = 0; i < UnitList.Count; i++)
{
yield return StartCoroutine(UnitList[i].GetComponent<BattleUnit>().Action());
}
for (int i = 0; i < UnitList.Count; i++)
{
IEnumerator x = UnitList[i].GetComponent<BattleUnit>().Action();
yield return StartCoroutine(x);
}
for (int i = 0; i < UnitList.Count; i++)
{
IEnumerator x = UnitList[i].GetComponent<BattleUnit>().Action();
Coroutine y = StartCoroutine(x);
yield return y;
}
}
}
上面是管理器类,挂载在上图的同名空物体上。用来执行顺序逻辑,按照列表UnitList执行。
已经在Inspector中设置好了。重点是利用协程实现等待效果的思想,yield return (Coroutine) 括号中应写入某个协程,注意不要写入IEnumertor类型的变量,不会报错但是没有效果。
执行结果:
每间隔 2 秒轮到下一头熊行动。
优化行动顺序判定
我们知道,在许多回合制游戏中,会有一个或多个因素决定轮换顺序,列如For the King中就是依靠敏捷来决定行动顺序。
using System.Collections;
using UnityEngine;
public class BattleUnit : MonoBehaviour
{
public new string name;
public float speed;
public IEnumerator Action()
{
print(name + "行动!");
yield return new WaitForSeconds(2f);
}
}
为此,我们为BattleUnit添加speed字段,用以决定行动顺序。
还为熊熊们增加了鬼怪作为对手,并设置他们的速度为:
熊大 1,熊二 2,熊三 3,鬼1 11,鬼2 12,鬼3 13。
也就是说排序好后执行顺序为:鬼3》鬼2》鬼1》熊三》熊二》熊大。
更新战斗管理器脚本为
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BattleManager : MonoBehaviour
{
public List<GameObject> UnitList;
private void Awake()
{
ScheduleBattleUnit();
}
private IEnumerator Start()
{
for (int i = 0; i < UnitList.Count; i++)
{
yield return StartCoroutine(UnitList[i].GetComponent<BattleUnit>().Action());
}
}
private void ScheduleBattleUnit()//排序战斗单位,依据每个单位的速度,决定行动顺序
{
//用冒泡排序根据速度将列表降序
int Count = UnitList.Count;
List<GameObject> list = UnitList;
for (int i = Count;i >= 0;i--)
{
for(int j = 1;j < i;j++)
{
//如果前一个单位的速度小于后面一个,则把后一个单位的速度与前一个交换,以实现速度越快越先行动
if (list[j-1].GetComponent<BattleUnit>().speed < list[j].GetComponent<BattleUnit>().speed)
{
GameObject temp = list[j-1];
list[j-1] = list[j];
list[j] = temp;
}
}
}
}
}
这样一来,执行结果就变成了:
符合需求!