协同程序

public class L7 : MonoBehaviour
{
    Thread t;
    //申明一个变量作为一个公共内存
    Queue <Vector3> queue = new Queue <Vector3> ();
    // Start is called before the first frame update
    void Start()
    {
        //unity支持多线程
        //但是新开的线程无法访问unity相关对象的内容,unity相关对象的信息只能在主线程中获取
        //要记得关闭unity中的多线程

        t = new Thread(Test);
        t.Start();

        //协同程序 - 协程
        //假的多线程,不是多线程
        //主要作用时将代码分时执行,不卡主线程
        //把可能会让主线程卡顿的耗时的逻辑分时分步执行
        //主要用于:
        //异步加载文件
        //异步下载文件
        //场景异步加载
        //批量创建时防止卡顿

        //协程和线程的却别
        //线程是独立出来的,和主线程并行执行
        //协程是在原线程里开启,进行逻辑分时分步执行

        //协程的使用
        //申明协程函数
        //协程函数返回值为IEnumerator类型及其子类
        //协程函数中通过yield return 返回值进行返回

        //开启协程函数
        //协程函数不能直接调用
        //开启方法一
        Coroutine c1 =  StartCoroutine(MyCoroutine(1, "123"));
        //开启方法二
        IEnumerator ie = MyCoroutine(1, "123");
        Coroutine c2 =  StartCoroutine(ie);

        //关闭协程
        //关闭所有协程,unity中可以开启多个协程
        StopAllCoroutines();

        //关闭指定协程
        //通过startcoroutine返回的协程对象关闭
        StopCoroutine(c1);

        //返回值不同的含义
        //下一帧执行
        //yield return 数字;
        //yield return null;
        //在update和lateupdate之间执行

        //等待指定秒数之后执行
        //yield return new WaitForSeconds(秒);
        //在Update和LateUpdate之间执行

        //等待下一个固定物理帧更新时执行
        //yield return new WaitForFixedUpdate();
        //在FixedUpdate和碰撞检测相关函数之后执行

        //等待摄像机和GUI渲染完成后执行
        //yield return new WaitForEndOfFrame();
        //主要会用于截图
        //在LateUpdate之后的渲染相关处理完毕之后执行

        //一些特殊类型的对象,比如异步加载相关函数返回的对象
        //一般是在Update和LateUpdate之间执行

        //跳出协程
        //yield break;

        //协程受对象或脚本失活和销毁的影响
        //协程开启后
        //脚本和物体销毁,协程不会执行
        //物体失活协程不会执行,脚本失活协程依旧执行
    }
    public void Test()
    {
        print("New Thread");
    }
    //协程函数返回值必须是IEnumerator或它的子类
    IEnumerator MyCoroutine(int i ,string str)
    {
        print (i);
        //协程函数中必须使用yield return进行返回
        yield return new WaitForSeconds(5f);
        print(str);
        yield return new WaitForSeconds(1F);
        print("3");
        //协程中的死循环不会卡死主线程
        while (true)
        {
            print("5");
            yield return new WaitForSeconds(5f);
        }
    }
    private void OnDestroy()
    {
        //关闭线程
        t.Abort();
        t = null;
    }
    
}

public class TestClass
{
    int time;
    public TestClass(int time)
    {
        this.time = time;
    }
}
public class L7P2 : MonoBehaviour
{
    IEnumerator Test()
    {
        print("1");
        yield return 1;
        print("2");
        yield return 2;
        print("3");
        yield return new TestClass(10);
    }
    // Start is called before the first frame update
    void Start()
    {
        //协程本质
        //协程可以分成两部分
        //协程函数本体和协程调度器

        //协程函数本体就是一个能够中间暂停和返回的函数
        //协程调度器是unity内部实现的,会在对应时机帮助我们继续执行协程函数
        //Unity只实现了协程调度部分
        //协程的本体本质上就是一个C#的迭代器方法

        //协程本体是迭代器方法的体现
        //协程函数本体
        //如果我们不通过开启协程的方法执行协程,unity的协程调度器不会帮助我们管理协程函数
        //但是我们可以自己执行迭代器函数内容
        IEnumerator ie = Test();
        ie.MoveNext();//执行函数内容中遇到yield return之前的逻辑
        print(ie.Current);//得到yield return 返回的内容
        while (ie.MoveNext())//ie.MoveNext()得到一个bool,如果是true就说明yield return之后还有内容
        {
            print(ie.Current);
        }

        //协程调度器
        //开启协程相当于是把一个协程函数(迭代器)放入unity的写成调度器中帮我们管理进行执行
    }

}
posted @ 2025-03-21 17:39  cannedmint  阅读(14)  评论(0)    收藏  举报