Unity基础-协程

Unity基础-协程

四、协程

概述

协程(Coroutine),本质上并不是多线程,而是在当前线程中将代码分时执行,不卡主线程。可以理解为,协程会把可能使主线程卡顿的程序分时分布进行。
协程通常用来:加载场景,异步加载文件,异步下载文件,批量创建物体防止卡顿。

协程与线程的区别

  • 新开一个线程是独立的一个管道,和主线程并行。Unity支持多线程,但是新开的线程无法访问Unity中的任何东西,只能靠中间枢纽和Unity主线程联络。
  • 新开一个协程是在原线程之上开启,进行逻辑分时分布执行。

协程的使用

协程可以分为两部分:1.协程函数本体,2.协程调度器。
协程本体就是一个能够中间暂停返回的函数。协程调度器是Unity内部实现的,会在对应的时机帮助我们继续执行协程函数。Unity只实现了协程调度的部分。
协同函数返回值必须是IEnumerator类型或者继承他的类型。

// 声明协程
IEnumerator MyCoroutineExample()
{print("111");yield return new WaitForSeconds(2);print("222");
}// 启动协程
StartCoroutine(MyCoroutineExample());// 关闭全部协程
StopAllCoroutines(); // 关闭特定协程
Coroutine co1 = StartCoroutine(MyCoroutineExample());
StopCoroutine(co1);

协程函数本体与C#迭代器

协程的本体本质上就是一个C#迭代器的方法。
C# 迭代器(Iterator)是一种特殊的方法或 get 访问器,允许你通过 yield return 语句逐步返回集合中的每个元素,而无需构建整个集合。它使得遍历自定义集合类型变得非常简单和高效。
IEnumerableIEnumerable<T> 接口的作用是使一个类型能够被 foreach 语句遍历。简单来说,只要一个类型实现了 IEnumerable (或 IEnumerable<T>),你就可以在 foreach 循环中使用它。

如果我们不通过Unity中给的开启协程的方法开启协程,Unity的协程调度器就不会帮我们管理协程函数。但是我们可以自己执行迭代器函数内容。
继承MonoBehavior后,开启协程,相当于把一个协程函数放入Unity的协程调度器中帮助我们管理进行执行,具体的 yield return 后面的规则也是Unity实现定义好的。

yield return 的含义和类型

yield return 语句是协程的核心,它控制协程的暂停和恢复时机,并可以返回不同类型的对象以实现不同的等待逻辑。

  1. 下一帧执行

    • yield return 数字; (通常 yield return 0; 或其他数字,但通常用 null)
    • yield return null;
    • UpdateLateUpdate 之间执行。
  2. 等待指定秒后执行

    • yield return new WaitForSeconds(秒);
    • UpdateLateUpdate 之间执行。
  3. 等待下一个固定物理帧更新时执行

    • yield return new WaitForFixedUpdate();
    • FixedUpdate 和碰撞检测相关函数之后执行。
  4. 等待摄像机和 GUI 渲染完成后执行

    • yield return new WaitForEndOfFrame();
    • LateUpdate 之后的渲染相关处理完毕后执行。
  5. 一些特殊类型的对象

    • 比如异步加载相关函数返回的对象(AsyncOperation)。
    • 通常在异步加载资源、异步加载场景、网络加载时使用。
    • 一般在 UpdateLateUpdate 之间执行。
  6. 跳出协程

    • yield break;:用于提前终止协程的执行。

协程应用示例:计时器与大量对象生成

习题要求
  1. 利用协程制作一个简单的秒表计时器,每秒在控制台打印当前秒数。
  2. 使用协程在场景中随机位置生成100000个立方体,确保在生成过程中不会出现明显的卡顿,这可以通过在适当的时机使用 yield return null; 实现。
代码实现
点击展开/折叠 协程实现代码
using System.Collections;
using UnityEngine;
using Random = UnityEngine.Random; // 明确指定Random命名空间,避免和System.Random冲突public class CoroutineExamples : MonoBehaviour
{int time = 0;// 启动协程void Start(){StartCoroutine(MyTimerCoroutine()); // 更名为MyTimerCoroutineStartCoroutine(CreateManyCubesCoroutine()); // 更名为CreateManyCubesCoroutine}// 计时器协程IEnumerator MyTimerCoroutine(){while (true){print("秒" + time);time++;yield return new WaitForSeconds(1);}}// 生成大量立方体协程IEnumerator CreateManyCubesCoroutine(){for (int i = 0; i < 100000; i++){GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);obj.transform.position = new Vector3(Random.Range(-100, 100), Random.Range(-100, 100), Random.Range(-100, 100));if (i % 1000 == 0) // 每生成1000个立方体暂停一帧,避免卡顿{yield return null;}}}
}

总结

你可以简化理解迭代器函数:C# 看到迭代器函数和 yield return 语法糖,就会把原本是一个的函数变成"几部分"。我们可以通过迭代器从上到下遍历这"几部分"进行执行,就达到了将一个函数中的逻辑分时执行的目的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/86720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UniApp组件封装,2025年最新HarmonyOS鸿蒙模块化开发项目式教程

一、环境配置与前置条件 ‌开发工具要求‌ HBuilderX 4.64&#xff08;鸿蒙插件已预装&#xff09;DevEco Studio 5.0.3.400&#xff08;真机调试必备&#xff09;鸿蒙离线SDK&#xff08;通过HBuilderX导入&#xff0c;每个项目独立配置&#xff09; ‌项目初始化 # 创建Vu…

C++ 精简知识点

目录 一、核心语法 1.指针VS引用 2. 类与对象&#xff08;必写代码&#xff09; 3. 继承与多态&#xff08;必写代码&#xff09; 4. 模板&#xff08;必写代码&#xff09; 5.智能指针 6. 异常处理&#xff08;必写结构&#xff09; 二、简答题速记 三、考试应急策略 一…

7.Vue的compute计算属性

3.8. 【computed】 作用&#xff1a;根据已有数据计算出新数据&#xff08;和Vue2中的computed作用一致&#xff09;。 <template><div class"person">姓&#xff1a;<input type"text" v-model"firstName"> <br>名&am…

在VSCode中借助AI丰富C++Qt应用程序

随着国内外各类自动化编程助手的普及&#xff0c;作为传统桌面C开发者&#xff0c;也要及时地用上这样强大的工具。考虑到网速问题&#xff0c;国外的服务时断时续&#xff0c;还是倾向于使用一些国产的大语言模型助手。我们今天就来看看在VSCode下使用大语言模型辅助Qt开发。 …

Java八股文——JVM「内存模型篇」

JVM的内存模型介绍一下 面试官您好&#xff0c;您问的“JVM内存模型”&#xff0c;这是一个非常核心的问题。在Java技术体系中&#xff0c;这个术语通常可能指代两个不同的概念&#xff1a;一个是JVM的运行时数据区&#xff0c;另一个是Java内存模型&#xff08;JMM&#xff0…

RabbitMQ 高可用与可靠性保障实现

RabbitMQ 高可用与可靠性保障实现详解 一、高可用架构设计1.1 集群部署模式1.2 镜像队列&#xff08;Mirrored Queue&#xff09; 二、可靠性保障机制2.1 消息持久化2.2 确认机制&#xff08;Confirm & Ack&#xff09;2.3 死信队列&#xff08;DLX&#xff09; 三、容灾与…

12.7Swing控件6 JList

在 Java Swing 中&#xff0c;列表框&#xff08;JList&#xff09;是用于显示一组选项的组件&#xff0c;用户可以从中选择一个或多个项目。以下是关于 Swing 列表框的详细介绍&#xff1a; 1. 基本概念与用途 作用&#xff1a;以垂直列表形式展示选项&#xff0c;支持单选或…

C++: condition_variable: wait_for -> unlock_wait_for_lock?

作为C++的初学者,面临的一个很大的问题,就是很多的概念并不是可以通过名称直观的预知它要完成的细节,比如这里的condition_variable的wait_for。C++的设计意图好像是,我告诉你这样用,你只要这样做就行,又简单还实用!而且需要记住的规则量又大的惊人。最后看起来,更像是…

HTML版英语学习系统

HTML版英语学习系统 这是一个完全免费、无需安装、功能完整的英语学习工具&#xff0c;使用HTML CSS JavaScript实现。 功能 文本朗读练习 - 输入英文文章&#xff0c;系统朗读帮助练习听力和发音&#xff0c;适合跟读练习&#xff0c;模仿学习&#xff1b;实时词典查询 - 双…

【JUC面试篇】Java并发编程高频八股——线程与多线程

目录 1. 什么是进程和线程&#xff1f;有什么区别和联系&#xff1f; 2. Java的线程和操作系统的线程有什么区别&#xff1f; 3. 线程的创建方式有哪些? 4. 如何启动和停止线程&#xff1f; 5. Java线程的状态模型&#xff08;有哪些状态&#xff09;&#xff1f; 6. 调用…

LSTM-SVM多变量时序预测(Matlab完整源码和数据)

LSTM-SVM多变量时序预测&#xff08;Matlab完整源码和数据&#xff09; 目录 LSTM-SVM多变量时序预测&#xff08;Matlab完整源码和数据&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 代码主要功能 该代码实现了一个LSTM-SVM多变量时序预测模型&#xff0c…

ES6——数组扩展之Set数组

在ES6&#xff08;ECMAScript 2015&#xff09;中&#xff0c;JavaScript的Set对象提供了一种存储任何值唯一性的方式&#xff0c;类似于数组但又不需要索引访问。这对于需要确保元素唯一性的场景非常有用。Set对象本身并不直接提供数组那样的方法来操作数据&#xff08;例如ma…

日志收集工具-logstash

提示&#xff1a;Windows 环境下 安装部署 logstash 采集日志文件 文章目录 一、下载二、解压部署三、常用插件四、常用配置 Logstash 服务器数据处理管道&#xff0c;能够从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的存储库中。Logstash 没…

6个月Python学习计划 Day 21 - Python 学习前三周回顾总结

✅ 第一周&#xff1a;基础入门与流程控制&#xff08;Day 1 - 7&#xff09; “打地基”的一周&#xff0c;我们走完了从变量、输入输出、判断、循环到第一个小型系统的完整链路。 &#x1f4d8; 学习重点&#xff1a; Python 基础语法&#xff1a;变量类型、字符串格式化、注…

Spring Boot SQL数据库功能详解

Spring Boot自动配置与数据源管理 数据源自动配置机制 当在Spring Boot项目中添加数据库驱动依赖&#xff08;如org.postgresql:postgresql&#xff09;后&#xff0c;应用启动时自动配置系统会尝试创建DataSource实现。开发者只需提供基础连接信息&#xff1a; 数据库URL格…

java每日精进 6.11【消息队列】

1.内存级Spring_Event 1.1 控制器层&#xff1a;StringTextController /*** 字符串文本管理控制器* 提供通过消息队列异步获取文本信息的接口*/ RestController RequestMapping("/api/string-text") public class StringTextController {Resourceprivate StringTex…

【凌智视觉模块】rv1106 部署 ppocrv4 检测模型 rknn 推理

PP-OCRv4 文本框检测 1. 模型介绍 如有需要可以前往我们的仓库进行查看 凌智视觉模块 PP-OCRv4在PP-OCRv3的基础上进一步升级。整体的框架图保持了与PP-OCRv3相同的pipeline&#xff0c;针对检测模型和识别模型进行了数据、网络结构、训练策略等多个模块的优化。 从算法改…

uniapp Vue2 获取电量的独家方法:绕过官方插件限制

在使用 uniapp 进行跨平台应用开发时&#xff0c;获取设备电量信息是一个常见的需求。然而&#xff0c;uniapp 官方提供的uni.getBatteryInfo方法存在一定的局限性&#xff0c;它不仅需要下载插件&#xff0c;而且目前仅支持 Vue3&#xff0c;这让使用 Vue2 进行开发的开发者陷…

Go语言中的if else控制语句

if else是Go语言中最基础也最常用的条件控制语句&#xff0c;用于根据条件执行不同的代码块。下面我将详细介绍Go语言中if else的各种用法和特性。 1. 基本语法 1.1. 最简单的if语句 if 条件表达式 {// 条件为true时执行的代码 } 示例&#xff1a; if x > 10 {fmt.Prin…

[Spring]-AOP

AOP场景 AOP: Aspect Oriented Programming (面向切面编程) OOP: Object Oriented Programming (面向对象编程) 场景设计 设计: 编写一个计算器接口和实现类&#xff0c;提供加减乘除四则运算 需求: 在加减乘除运算的时候需要记录操作日志(运算前参数、运算后结果)实现方案:…