Unity多线程和协程

这篇具有很好参考价值的文章主要介绍了Unity多线程和协程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.Unity是否支持多线程?

Unity支持多线程的使用,可以使用C#的Thread类来创建和管理线程,只需要引入这个类:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

但需要注意的是,在Unity中,只有主线程(也称为渲染线程)可以访问Unity对象,如GameObject、Transform等,如果在其他线程中访问这些对象,会导致不可预期的结果。

因此,在使用多线程时,需要遵循一些规则:

  1. 不要在非主线程中访问Unity对象;

  2. 不要在多个线程中同时修改同一个对象或变量,否则可能会导致竞态条件;

  3. 不要过度使用多线程,因为线程切换会带来额外的开销,而且多线程可能会增加代码复杂性和调试难度;

  4. Unity中的多线程记得使用后要关闭,否则会在推出调试后一直运行,直到关闭Unity或者改变相应的脚本代码。

示例: 

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

 新开的线程虽然不能访问Unity中的对象,但是多线程可以进行一些复杂的逻辑计算:例如A*算法、网格计算,复杂的计算可能会卡住主线程,因此我们用副线程去计算。算好了,主线程再去调用。

示例:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

 unity 多线程,Unity基础知识学习记录,unity,游戏引擎

 unity 多线程,Unity基础知识学习记录,unity,游戏引擎

 二.什么是协程?

协程全称协同程序,不同于多线程,它不是一个线程,依附于Unity主线程。

  • 新开一个线程是独立的一个管道,和主线程并行执行;
  • 新开一个协程是在原线程之上开启,进行逻辑分时分步执行;

主要作用:

        协程适合处理需要分阶段执行的操作,如动画、延迟执行等。协程可以让程序在一定时间后再次执行,而不会阻塞主线程。这样可以避免线程切换带来的开销,提高程序性能。

        也就是说,协程是把可能会让主线程卡顿的耗时操作分时分步进行。

主要适用场景:

        异步加载文件、异步下载文件、场景异步加载、批量创建时防止卡顿。


        协程可以将一个函数分成多个部分,在每个部分执行完后暂停,等待下一次唤醒继续执行。如果不唤醒,这个协程就会被挂起。这种方式可以有效地控制程序的执行流程,使得我们可以更加灵活地控制程序的运行逻辑。

三.协程的使用

首先,要想使用协程,类要继承MonoBehavior;

在Unity中,我们可以使用Coroutine类来创建协程。通常情况下,我们会将协程定义为一个函数(使用IEnumerator关键字),然后通过StartCoroutine方法启动它。

示例:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

        在这个例子中,我们定义了一个名为MyCoroutine的协程函数,该函数使用yield语句分别暂停1秒和2秒,并在每次暂停后输出一条调试信息。然后,在Start函数中,我们通过StartCoroutine方法启动了这个协程。

        需要注意的是,协程函数必须返回IEnumerator类型,而不是void类型。协程函数中使用yield语句来暂停执行,并返回一个对象,告诉协程系统应该何时继续执行。


        协程可以通过传递参数来控制它们的行为。我们可以将参数作为协程函数的参数,并在启动协程时传递给它。

 示例:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

        在这个例子中,我们定义了一个名为MyCoroutine的协程函数,该函数接受两个参数:一个字符串和一个浮点数。然后,在Start函数中,我们通过StartCoroutine方法启动了这个协程,并将"Hello"和3分别作为参数传递给它。

        需要注意的是,在协程函数内部,我们可以像普通函数一样使用传递进来的参数。但是,在协程函数之外,我们不能直接访问协程内部的变量。如果需要在协程之间共享数据,可以考虑使用静态变量或其他线程安全的机制。

不同的yield return

  1. yield return null:暂停协程一帧,然后继续执行下一帧, 在Update和LateUpdate之间执行;

  2. yield return new WaitForSeconds(float seconds):暂停协程指定时间后继续执行,在Update和LateUpdate之间执行;

  3. yield return new WaitForEndOfFrame():暂停协程直到当前帧渲染完毕后(摄像机和GUI)继续执行,在LateUpdate之后的渲染相关处理之后执行;

  4. yield return new WaitForFixedUpdate():暂停协程直到下一次FixedUpdate后继续执行,在FixUpdate和碰撞检测相关函数之后执行;

  5. yield return StartCoroutine(coroutine):暂停当前协程并启动一个新的协程,直到新的协程执行完成后继续执行当前协程。

  6. yield break:结束当前协程的执行。

 四.协程受对象和组件失活销毁的影响

当我们开启了一个协程,如果

  • 挂载此脚本的组件和物体销毁,协程将不会执行;
  • 物体失活协程不执行;
  • 组件失活协程执行。

五.协程的原理 

协程的本质:

        协程的本质是利用迭代器(Iterator)来实现的。在C#中,迭代器是一种特殊的对象,它可以在循环中依次返回集合中的元素。在协程中,yield return语句返回的也是一个迭代器对象,当协程执行到yield return语句时,会将执行权交给调用者,并返回一个迭代器对象,等待调用者再次调用协程来继续执行。这样就实现了协程的暂停和继续执行功能。

        所以在脚本中调用协程相当于是把一个协程函数(迭代器)放入Unity的协程调度器(StartCoroutine()函数)中帮助我们管理进行执行,具体的yield return 后面的规则,也是Unity定义的一些规则。

        我们通过获取IEnumerator对象手动模拟协程的管理;

定义一个协程函数,无法单独调用:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

 获取这个协程对象:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

      IEnumerator内部方法,属性如下:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

执行MoveNext(),控制台会输出“test 1”,执行了一行语句;

执行Reset(),控制台会输出 “1”, 打印的是yield return 的返回值;

如果打印Current,控制台会输出yield return的参数值;

例如这种写法,Reset会输出“123 Vector3”,Current会输出“123 (1,2,3)”;

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

 另一个问题来了,我们可以用MoveNext()和Current来一步步执行协程函数。但是如果协程函数中有n个yield return 怎么办?写n个MoveNext()和Current吗?

 注意:MoveNext()返回bool值,当协程函数内还有可以执行的内容时返回true,没有返回flase。

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

使用while输出执行协程函数中的所有值:

unity 多线程,Unity基础知识学习记录,unity,游戏引擎

总结:

        协程的本质就是利用C#的迭代器函数“分步执行”的特点加上协程调度逻辑实现的一套分时执行函数的规则。文章来源地址https://www.toymoban.com/news/detail-592657.html

到了这里,关于Unity多线程和协程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • rust写一个多线程和协程的例子

    当涉及到多线程和协程时,Rust提供了一些非常强大的工具,其中最常用的库之一是 tokio ,它用于异步编程和协程。下面我将为你展示一个简单的Rust程序,演示如何使用多线程和协程。 首先,你需要在你的项目的 Cargo.toml 文件中添加 tokio 库的依赖: [dependencies] tokio = { versi

    2024年02月11日
    浏览(49)
  • Unity中的热更新的基础知识,Xlua与ILRuntime基础知识

    热更新是指在不需要重新编译打包游戏的情况下,在线更新游戏中的一些非核心代码和资源,比如活动运营和打补丁。热更新分为资源热更新和代码热更新两种,代码热更新实际上也是把代码当成资源的一种热更新,但通常所说的热更新一般是指代码热更新。资源热更新主要

    2023年04月09日
    浏览(85)
  • Unity读书系列《Unity3D游戏开发》——基础知识

    本篇对应标题书籍的第一章基础知识,也就是unity的基本常识和工作流的说明。 Unity目前用于创建2D和3D游戏、模拟应用程序、可视化体验以及其他虚拟现实(VR)和增强现实(AR)应用,游戏工业两开花。 Unity初版是在2005年发布的,开始时用unity3.X、4.X这样的名称进行版本更新

    2024年01月18日
    浏览(82)
  • Unity | Shader基础知识(第一集:unity中最简单的shader)

    目录 一、unity的shader 二、创建一个shader(在创建时,选前三种都可以) 三、内容解读 1.shader一直都在 2.我们写shader在写什么 四、没有被干预的shader(最简单的shader) 相关阅读 编写着色器概述 - Unity 手册 一、unity的shader unity写的shader并不是真正意义上的shader。 官方解释:

    2024年02月04日
    浏览(51)
  • 深入分析 Java、Kotlin、Go 的线程和协程

    Go 语言比 Java 语言性能优越的一个原因,就是轻量级线程 Goroutines (协程Coroutine)。本篇文章深入分析下 Java 的线程和 Go 的协程。 协程并不是 Go 提出来的新概念,其他的一些编程语言,例如:Go、Python 等都可以在语言层面上实现协程,甚至是 Java,也可以通过使用扩展库来

    2024年02月01日
    浏览(39)
  • 不同开发语言在进程、线程和协程的设计差异

    在多线程项目开发时,最常用、最常遇到的问题是 1,线程、协程安全 2,线程、协程间的通信和控制 本文主要探讨不同开发语言go、java、python在进程、线程和协程上的设计和开发方式的异同。 进程 进程是 操作系统进行资源分配的基本单位,每个进程都有自己的独立内存空

    2024年01月22日
    浏览(35)
  • Unity | Shader基础知识(什么是shader)

    Shader的中文名叫着色器。 着色器的作用: 这个世界是3D的,包括在Unity的场景中,我们建的球球,方块块之类的,都是3D的,但是,屏幕是2D的,把3D的东西,通过颜色的汇总,显示在2D的屏幕上。 想知道颜色是怎么合到一起的,我们就找个图片,把它拆开看。 因为世界上所有

    2024年02月15日
    浏览(61)
  • Unity地面交互效果——3、曲面细分基础知识

    回到目录   大家好,我是阿赵。   之前介绍了使用动态法线贴图混合的方式模拟轨迹的凹凸感,这次来讲一下更真实的凹凸感制作。不过在说这个内容之前,这一篇先要介绍一下曲面细分着色器(Tessellation Shader)的用法。   之前通过法线贴图模拟了凹凸的感觉:   法

    2024年02月05日
    浏览(51)
  • Unity基础知识笔记(三)——NGUI中的UIInput

    NGUI中的UIInput的使用_ngui uiinput-CSDN博客 https://blog.csdn.net/MonoBehaviour/article/details/78423299?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171023629716800180684601%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257Drequest_id=171023629716800180684601biz_id=0utm_medium=distribute.pc_search_result.none-task-blog-2~all~so

    2024年03月25日
    浏览(36)
  • Unity基础知识之顶点吸附、创建组合体

    顶点吸附 :选择物体后按住键盘上的 V键 ,鼠标定点定位,再拖拽到目标物体对齐即可。 注:操作成功后先松 V键 。 1、两个平面Plane的顶点吸附 2、两个物体cube的顶点吸附 组合体子弹由2个capsule(胶囊)、1个cylinder(圆柱体)组成,如图先创建这3个对象。 再将其中一个c

    2023年04月25日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包