IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 协程 IEnumerator 学习笔记21 -> 正文阅读

[游戏开发]协程 IEnumerator 学习笔记21

协程 有人说在4.0以上的.net中已被弃用 用了新的方法替代
https://stackoverflow.com/questions/64258574/what-is-an-ienumerator-in-c-sharp-and-what-is-it-used-for-in-unity
说如果每次spawn时遵循斐波那契数列
这种update会很难写
先放着

StartCoroutine 用来启动协程
协程的执行可以在任何时候使用 yield 语句暂停。当使用 yield 语句时,协程会暂停执行并在下一帧自动恢复 StartCoroutine 方法在第一个 yield 返回时返回,但是您可以 yield 结果,它会等待协程完成执行。
不能保证协程以它们开始的相同顺序结束,即使它们在同一帧中完成。
任何类型的输出(包括 null)都会导致执行在稍后的帧上返回,除非协程停止或已完成。
StartCoroutine官方文档
https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
第一个例子 使用了WaitForSeconds 时间不精确 跑到53分钟时 打印出了奇数时间

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    private IEnumerator coroutine;
    void Start()
    {
        print("Starting " + Time.time);
        coroutine = WaitAndPrint(2.0f);
        StartCoroutine(coroutine);
        print("Before WaitAndPrint Finishes " + Time.time);
    }
    private IEnumerator WaitAndPrint(float waitTime)
    {
        while (true)
        {
            print("Start协程" + Time.time);
            yield return new WaitForSeconds(waitTime);
            print("完成协程 " + Time.time);
        }
    }
}

结果是输出
Starting 0
Start协程0
Before WaitAndPrint Finishes0
完成协程 2.000603
Start协程2.000603
完成协程 4.001181
Start协程4.001181

第二个例子

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    IEnumerator Start()
    {
        print("Starting " + Time.time);
        yield return StartCoroutine(WaitAndPrint(2.0f));
        print("Done " + Time.time);
    }
    IEnumerator WaitAndPrint(float waitTime)
    {
        print("Start协程 " + Time.time);
        yield return new WaitForSeconds(waitTime);
        print("WaitAndPrint " + Time.time);
    }
}

结果是输出
Starting 0
Start协程 0
WaitAndPrint 2.001024
Done 2.001024

第三个例子

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    IEnumerator Start()
    {
        print("Start开始 " + Time.time);
        StartCoroutine("DoSomething", 2.0f);
        yield return new WaitForSeconds(1);
        StopCoroutine("DoSomething");
        print("start结束 " + Time.time);
    }
    IEnumerator DoSomething(float someParameter)
    {
        while (true)
        {
            print("Start协程" + Time.time);
            yield return null;
            print("协程完成" + Time.time);
        }
    }
}

结果是输出
Start开始 0
Start协程0
协程完成0.02
Start协程0.02
协程完成0.3533334
Start协程0.3533334

协程完成0.99992
Start协程0.99992
协程完成1.001271
Start协程1.001271
start结束 1.001271

官方说这是invoke的替代用法 但但这有误差完全不想用

第四个例子

using System.Collections;
using UnityEngine;

public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        print("Start开始 " + Time.time);
        StartCoroutine(coroutineA());
        print("start结束 " + Time.time);
    }
    IEnumerator coroutineA()
    {
        print("Start协程A" + Time.time);
        yield return new WaitForSeconds(1.0f);
        yield return StartCoroutine(coroutineB());
        print("协程A完成" + Time.time);
    }
    IEnumerator coroutineB()
    {
        print("Start协程B" + Time.time);
        yield return new WaitForSeconds(2.5f);
        print("协程B完成" + Time.time);
    }
}

结果是输出
Start开始 0
Start协程A0
start结束 0
Start协程B1.000296
协程B完成3.500929
协程A完成3.500929

测试例1 null

using System.Collections;
using UnityEngine;

public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        print("Start开始 " + Time.time);
        StartCoroutine(coroutineA());
        print("start结束 " + Time.time);
    }
    IEnumerator coroutineA()
    {
        print("Start协程A" + Time.time);
        yield return null;
        print("协程A完成" + Time.time);
    }
}

结果是输出
Start开始 0
Start协程A0
start结束 0
协程A完成0.02

测试例2 while(true){yield return null;}

using System.Collections;
using UnityEngine;

public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        print("Start开始 " + Time.time);
        StartCoroutine(coroutineA());
        print("start结束 " + Time.time);
    }
    IEnumerator coroutineA()
    {
        while (true)
        {
            print("Start协程A" + Time.time);
            yield return null;
            print("协程A完成" + Time.time);
        }
    }
}

结果是输出
Start开始 0
Start协程A0
start结束 0
协程A完成0.02
Start协程A0.02
协程A完成0.3533334
Start协程A0.3533334

结合官方例1结论 只要有while true 不管yield return是 null还是 new WaitForSeconds 就是无限输出

测试例3 官方例4 去除 yield return new WaitForSeconds(1.0f);

using System.Collections;
using UnityEngine;

public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        print("Start开始 " + Time.time);
        StartCoroutine(coroutineA());
        print("start结束 " + Time.time);
    }
    IEnumerator coroutineA()
    {
        print("Start协程A" + Time.time);
        yield return StartCoroutine(coroutineB());
        print("协程A完成" + Time.time);
    }
    IEnumerator coroutineB()
    {
        print("Start协程B" + Time.time);
        yield return new WaitForSeconds(2.5f);
        print("协程B完成" + Time.time);
    }
}

结果是输出
Start开始 0
Start协程A0
Start协程B0
start结束 0
协程B完成2.500149
协程A完成2.500149
结论是StartCoroutine可以作为标准协程结束的条件

FIxedUpdate是精确的0.02 跟timeScale有关但却不受影响
https://docs.unity3d.com/ScriptReference/WaitForSeconds.html
https://docs.unity3d.com/ScriptReference/Time-timeScale.html
Time.timeScale也是1 而输出时就是2.001左右 每次都会不同 官方文档说的可能会不同 但我没法判断是不是那种情况 然后官方说了WaitForSecondsRealtime 未缩放的 但时间也不是精确的2秒 (居然小于2)(看来计时器也不能使用协程 不精确)


Coroutine官方文档
协程是一个可以暂停执行(yield)直到给定的 YieldInstruction完成的函数。
https://docs.unity3d.com/ScriptReference/Coroutine.html
第一个例子使用了WaitForSeconds 时间不精确

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    IEnumerator Start()
    {
        print("Starting " + Time.time);
        yield return StartCoroutine("WaitAndPrint");
        print("Done " + Time.time);
    }
    IEnumerator WaitAndPrint()
    {
        print("Start协程" + Time.time);
        yield return new WaitForSeconds(5);
        print("协程完成" + Time.time);
    }
}

结果是输出
Starting 0
Start协程0
协程完成5.000767
Done 5.000767
结论 StartCoroutine可以作为start协程结束的条件

第二个例子没有使用WaitForSeconds 时间也不精确 也是是2.001左右; 第二个例子区别就是介绍了变量 其他一样

IEnumerator Start()
就是一种特殊的自己启动的协程
https://forum.unity.com/threads/why-change-void-start-to-ienumerator-start.455280/
https://answers.unity.com/questions/754968/can-monobehaviorstart-return-an-ienumerator-hint-y.html

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-03 17:21:42  更:2021-10-03 17:23:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 2:36:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码