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 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity中迭代器和协程的部分概念 -> 正文阅读

[游戏开发]Unity中迭代器和协程的部分概念

协程本质上也是一个迭代器,为了记录一下今天对二者的学习和巩固记录一下今天的知识点。
首先了解一下迭代器的知识:
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。C#中使用IEnumerator接口实现,Java中使用Iterator接口实现,其中原理都差不多,下面我就用C#代码来演示下迭代器的实现。

namespace System.Collections//这是C#的迭代器底层方法
{
    public interface IEnumerator
    {
        object Current { get; } //
        bool MoveNext();
        void Reset();
    }
}

Current
是作为返回的正确对象,获取当前下标所指向的对象。如我们foreach时遍历返回的那个正确对象
MoveNext
即是遍历该对象时,检查并确认下一个位置的对象是否为空,如foreach时编译器来判断是否遍历到最后一个
Reset
是我们在多次使用迭代器时下标如果不更新为第一个的话,那么Current就会一直是上一次操作读取下标的对象,如果我们需要重新遍历则该下标之前的数据就找不到。所以Reset则是更新下标为第一个。

迭代器的一大特点就是可以数据封装起来,无论什么类型的数据都可以放到一个迭代器里,方便管理和读取。这样我们就可以根据自己开发需要去创建自己的数据类型,再利用迭代器去管理和遍历获取。
简单的重写一下三个方法加深理解

Current(){
Get{
    return List[index];
}
}
MoveNext(){
If(index<list.Length)
{
    Return true;
}
Else
    Return false
}
Reset()
{
Current = null;
Index = 0 ;
}

接下来就是协程的部分知识和代码
Unity在每一帧(Frame)都回去处理对象上的协程。Unity主要是在Update后去处理协程(检查协程的条件是否满足),但也有些特例
协程与Update一样,每帧处理,如果yield条件满足,就会执行协程方法后面的代码
协程不是异步执行,他是串行逻辑。不需要考虑同步和锁的问题
咱们先用一段代码来显示一下,Monobehaviour中代码的执行顺序和协程运行时的时间记录以及逻辑顺序输出

public class xiecheng : MonoBehaviour
{
    private bool isStartCall = false;
    private bool isUpdateCall = false;
    private bool isLateUpdateCall = false;
    // Start is called before the first frame update
    void Start()
    {
        //Debug.Log("hello ");
        if (!isStartCall)
        {
            Debug.Log("Start Call Begin: " + Time.time);
            StartCoroutine(StartCoutine());
            Debug.Log("Start Call End: " + Time.time);
            isStartCall = true;
        }
    }
    
    IEnumerator StartCoutine()
    {
        
        Debug.Log("This is Start Coroutine Call Before: " + Time.time  );
        yield return null;
        Debug.Log("This is Start Coroutine Call End: " + Time.time);
    }
    // Update is called once per frame
    void Update()
    {
        if (!isUpdateCall)
        {
            Debug.Log("Update Call Begin: " + Time.time);
            StartCoroutine(UpdateCoutine());
            Debug.Log("Update Call End: " + Time.time);
            isUpdateCall = true;
        }
    }
    IEnumerator UpdateCoutine()
    {
        Debug.Log("This is Update Corourine Call Before: " + Time.time);
        yield return new WaitForSeconds(1f);
        Debug.Log("This is Update Coroutine Call End: " + Time.time);
    }
    private void LateUpdate()
    {
        if(!isLateUpdateCall)
        {
            Debug.Log("LateUpdate Call Begin: " + Time.time);
            StartCoroutine(LateCoutine());
            Debug.Log("LateUpdate Call End: " + Time.time);
            isLateUpdateCall = true;
        }
    }
    IEnumerator LateCoutine()
    {
        Debug.Log("This is Late Coroutine Call Before: " + Time.time);
        yield return new WaitForSeconds(1f);
        Debug.Log("This is Late Coroutine Call End: " + Time.time);
    }
}

大家可以先在脑子里或者记一下自己觉得应该执行输出的顺序和时间
我们接下来截取一下unity中的控制台输出
在这里插入图片描述
结合代码来理解,我们可以看到所有的协程在进入时都是跟着函数顺序按照正常逻辑执行第一句,但是yield之后就暂时不执行了,在第一个yield之前都是在第一帧中把所有的逻辑执行完,而第10行的debug则是yield return null即一帧之后再执行,我们也可以清晰的看到0.02秒之后执行,即一帧之后。而11与12行的debug则都是在1秒之后执行。
对应了yield return new waitforseconds(1f)
从这几个输出就很清晰地能够看出协程中yield的运行原理了。同时也能够巩固一下monobehaviour的函数执行顺序图。
在这里插入图片描述
协程还有一个特色是,他虽然写在Monobehaviour中,但是他的执行地位是和Monobehaviour同层级的,它并不会受到Monobehaviour的状态enable而影响,但它和Monobehaviour一样受挂载的游戏对象gameobject控制setactive()
再加一个简单的协程实现计时器功能的巩固吧

IEnumerator timer()
    {   
        Debug.Log(timernum);
        yield return new WaitForSeconds(1f);
        timernum -= 1;
        if (timernum < 0)
            StopCoroutine(timer());
        else
            StartCoroutine(timer());
    }
  游戏开发 最新文章
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
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:52:21  更:2022-05-05 11:54:30 
 
开发: 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/23 10:55:34-

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