unity 协程的帮助类

这是一个使用协程的帮助类,利用装饰模式的思想最大化解耦。代码如下:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class IEM : MonoBehaviour {

    private IEnumerator iem = null;

    public IEnumerator getIenumerator()
    {
        return iem;
    }


    //使用装饰模式来嵌套功能链条
    //给一个协程增加执行前逻辑以及执行后逻辑
    private IEnumerator _ACT(IEnumerator i, Action after = null, Action before = null)
    {
        if (before != null)
            before();

        if (i != null)
            yield return StartCoroutine(i);

        if (after != null)
            after();
    }

    //延迟一定时间后执行
    private IEnumerator _DELAY(IEnumerator i, float time)
    {
        if (time > 0)
            yield return new WaitForSeconds(time);

        if (i != null)
            yield return StartCoroutine(i);

    }

    //执行后等待一定时间
    private IEnumerator _WAIT(IEnumerator i, float time)
    {
        if (i != null)
            yield return StartCoroutine(i);

        if (time > 0)
            yield return new WaitForSeconds(time);
    }

    //将两个协程链接在一起
    private IEnumerator _JOIN(IEnumerator start, IEnumerator end)
    {
        if (start != null)
            yield return StartCoroutine(start);

        if (end != null)
            yield return StartCoroutine(end);
    }

    public IEnumerator _WHILE(IEnumerator m, IEnumerator n)
    {
        Coroutine c = null;
        Coroutine d = null;
        if (m != null)
            c = StartCoroutine(m);
        if (n != null)
            d = StartCoroutine(n);

        yield return m;
        yield return n;
    }

    //使用装饰模式思想 制造一个协程链条 
    //为了保证数据正确 原则上应从start 开始 end结束
    //开始
    public static IEM START()
    {
        GameObject s = new GameObject();
        s.AddComponent<IEM>();
        IEM d = s.GetComponent<IEM>() as IEM;
        
        return d;
    }

    public static IEM START(IEnumerator enm)
    {
        GameObject s = new GameObject();
        s.AddComponent<IEM>();
        IEM d = s.GetComponent<IEM>() as IEM;
        d.iem = enm;
        
        return d;
    }

    //结束时开始执行协程  以及加入群组
    public IEM END()
    {
        if (iem == null)
            return this;

        StartCoroutine(iem);
        iem = null;

        return this;
    }

    public IEM END(int group)
    {
        if (iem == null)
            return this;

        Coroutine c = StartCoroutine(iem);
        CRTS.Instance.Add(group, c);
        iem = null;

        return this;
    }
    

    //增加行为
    public IEM ACT(Action after = null, Action before = null)
    {
        iem = _ACT(iem, after, before);
        return this;
    }
    //增加下一个协程
    public IEM AFTER(IEnumerator after)
    {
        iem = _JOIN(iem, after);
        return this;
    }
    public IEM AFTER(IEM after)
    {
        return AFTER(after.getIenumerator());
    }
    //增加上一个协程
    public IEM BEFORE(IEnumerator before)
    {
        iem = _JOIN(before, iem);
        return this;
    }
    public IEM BEFORE(IEM before)
    {
        return BEFORE(before.getIenumerator());
    }
    //增加延迟时间 延迟运行当前协程
    public IEM TIME_BEFORE(float time)
    {
        iem = _DELAY(iem, time);
        return this;
    }
    //完成协程后等待一定时间
    public IEM TIME_AFTER(float time)
    {
        iem = _WAIT(iem, time);
        return this;
    }
    //与其他协程共同运行
    public IEM WHILE(IEnumerator enm)
    {
        iem = _WHILE(iem, enm);
        return this;
    }
    public IEM WHILE(IEM enm)
    {
        return WHILE(enm.getIenumerator());
    }
    //注意 多个参数的while与单参数的while结果有巨大区别
    //使用参数的while 表明 是前述协程运行完毕后再共同运行,函数生成一个新的iem返回
    //而单参数的while表明与前述协程共同运行 在原IEM 基础上生效
    public static IEM WHILE(params IEnumerator[] senm)
    {
        IEM temp = null;
        foreach(IEnumerator i in senm)
        {
            if (i != null && temp == null)
                temp = IEM.START(i);
            else
                temp = temp.WHILE(i);
        }
        return temp;
    }
    public static IEM WHILE(params IEM[] senm)
    {
        IEM temp = null;
        foreach (IEM i in senm)
        {
            if (i != null && temp != null)
                temp = i;
            else
                temp = temp.WHILE(i);
        }
        return temp;
    }

    //判断分支 
    public IEM IF(Func<bool> act,IEnumerator t = null,IEnumerator f = null)
    {
        bool bb = act();
        
        if (bb)
            return AFTER(t);
        else
            return AFTER(f);
    }
    public IEM IF(Func<bool> act, IEM t, IEnumerator f = null)
    {
        return IF(act,t.getIenumerator(),f);
    }
    public IEM IF(Func<bool> act, IEnumerator t, IEM f)
    {

        return IF(act, t, f.getIenumerator());
    }
    public IEM IF(Func<bool> act, IEM t , IEM f )
    {

        return IF(act, t.getIenumerator(), f.getIenumerator());
    }

}
使用:比如一个三消游戏,棋子定义了迭代器moveTo,棋盘定义了判断是否消除函数check则可以这样写代码:
[csharp] view plain copy
  1. IEM.START(g.MoveTo(l))  
  2.             .WHILE(l.MoveTo(g))  
  3.             .ACT(null, g.SetState_Switching).ACT(null, l.SetState_Switching)  
  4.             .TIME_AFTER(1.0f)  
  5.             .IF(check,IEM.START().ACT(g.SetState_death).ACT(l.SetState_death,IEM.WHILE(g.MoveTo(l),l.MoveTo(g)))  
  6.             .END();  

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页