实现unity的协同(Coroutine)

要用c#实现unity的协同,现需要了解c# 的yield用法.

为了简明起见,先上一个简化版本,只实现不带停止功能部分(即没StartCoroutine("xxx")和StopCoroutine("xxx"函数))。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace create_coroutine
{
    /// <summary>
    /// 同Unity一致
    /// </summary>
    public class WaitForSeconds
    {
        public float Elapse;//累加时间
        public float Time;//指定时间
        public WaitForSeconds(float t)
        {
            Time = t;
        }
    }

    /// <summary>
    /// 协同类
    /// </summary>
    class Corotine
    {
        static List<IEnumerator> Corotines = new List<IEnumerator>();
        static List<IEnumerator> TmpLst = new List<IEnumerator>();

        /// <summary>
        /// 开始协同程序
        /// </summary>
        /// <param name="c"></param>
        public static void Start(IEnumerator c)
        {
            Corotines.Add(c);
        }

        /// <summary>
        /// 主线程调用函数
        /// </summary>
        /// <param name="delta">两帧之间的时间间隔.单位:秒</param>
        public static void MainThread_Update(float delta)
        {
            TmpLst.Clear();

            foreach (IEnumerator c in Corotines)
            {
                if (c.Current == null
                    || (c.Current is int && ((int)c.Current == 0))) //判断是否等待一帧,和yield return break;(后者也会返回null,但是MoveNext()的结果是false.)
                {
                    bool r = c.MoveNext();
                    if(!r)
                        TmpLst.Add(c);  //注意:Corotines链表中的对象不能在foreach循环内删除
                }
                else if (c.Current.GetType() == typeof(WaitForSeconds)) //判断等待一段时间
                {
                    WaitForSeconds wfs = c.Current as WaitForSeconds;
                    wfs.Elapse += delta;  //逐帧累加时间
                    if (wfs.Elapse >= wfs.Time) //累加时间大于指定等待时间则跳过
                    {
                        bool r = c.MoveNext();
                        if (!r)
                            TmpLst.Add(c);
                    }
                }
                //...在此处可以加入其他判断 WaitForEndOfFrame 或者 WaitForFixedUpdate

            }


            foreach (IEnumerator c in TmpLst)
            {
                Corotines.Remove(c);
            }
        }
    }

    /// <summary>
    /// 测试用例
    /// </summary>
    class Program
    {
        static IEnumerator GetI()
        {
            yield return new WaitForSeconds(1F);
            Console.Write("a");
            yield return 0;
            Console.Write("b");
            yield return null;
            Console.Write("c");
        }

        static void Main(string[] args)
        {
            float delta = 0.005F;
            Corotine.Start(GetI());
            while (true)
            {
                DateTime timeStart = DateTime.Now;
                Corotine.MainThread_Update(delta);
                System.Threading.Thread.Sleep(5);
                delta = (float)(DateTime.Now - timeStart).TotalSeconds;
            }
        }
    }
}

后记:


unity用久了之后自然对其中的协同函数(coroutine)有一种依赖。

亦因为最近服务器程序的需求,所以手动实现一个协同机制来简化代码很有必要。

使用协同后对代码的好处可以参考c兄的:

点击打开链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值