协程实现回合制的基本方法

实现行动轮换的基本方式

        由女巫项目探究而来的优化版本。(框架)

        看上图,要求实现熊大,熊二,熊三按照顺序执行行动。

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;                    
                }
            }
        }
    }
}

这样一来,执行结果就变成了:

        

符合需求!

猜你喜欢

转载自blog.csdn.net/m0_73087695/article/details/134539913