封装和桥接Unity 协程体系

简介

        协程(Coroutine)在C#中是一种特殊的函数,它允许开发者编写可以暂停执行并在未来某个时刻恢复执行的代码块。协程通常用于实现异步操作,如延时执行、等待某个事件发生、或者分段执行复杂的任务。在Unity游戏引擎中,协程尤为重要,因为它们可以在不阻塞主线程的情况下执行这些操作。

        C#协程的实现依赖于迭代器(Iterator)和状态机(State Machine)。当编写一个协程时,你实际上是定义了一个返回IEnumerator类型的方法。这个方法内部可以包含yield语句,用于控制协程的执行流程。yield return语句可以返回一个值并暂停协程,直到下一帧或特定条件满足时再次执行。yield break语句则会完全结束协程的执行。

Unity 已经有了Async Operation,为什么还要二次封装或桥接呢?

        当然,它在某些情况下可以帮助我们解决很多令人很头疼的问题!例如:要等待一组Async Operation对象,同时要监控他们的进度;再例如,需要同时等待数目不确定的Async Operation,但是他们却来自于不同的系统;又或者,希望一段逻辑去控制Yield的完成状态,那么在这种情况下,桥接和封装是最好的选择。

它可以实现什么效果呢?

        下面这段代码展示了如何使用逻辑控制Yield Completed State,当W按键被按下后,yield return new .... 下面的代码才会被执行。

    private IEnumerator Start (){ Debug.Log($"Start: {Time.time}");yield return new XAsyncOperationCondition(a=>Pass);Debug.Log($"End: {Time.time}");}private void Update (){if ( Input.GetKey(KeyCode.W) ){Pass = true;}}

        下面这段代码展示了如何将来自不同系统的Async Operation 整合在一起,这对于同时处理不同管线的资产加载进度时非常有帮助。

    XAsyncOperationGroup HandleGroup;private IEnumerator Start (){var url = "https://img0.baidu.com/it/u=1799694557,1475747482&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750"; var fromWebHandle =  new XAsyncOperationWebTextureRequest(UnityWebRequestTexture.GetTexture(url).SendWebRequest());var fromResourceHandle = new XAsyncOperationResourceRequest<Texture>(Resources.LoadAsync("default.jpg"));var fromAddressableHandle = new XAsyncOperationAddressable<Texture>(Addressables.LoadAssetAsync<Texture>("default"));HandleGroup = new XAsyncOperationGroup(fromWebHandle, fromResourceHandle, fromAddressableHandle);yield return HandleGroup;//> fromWebHandle.Result//> fromResourceHandle.Result//> fromAddressableHandle.Result}private void Update (){if ( HandleGroup != null ){Debug.Log($"载入进度:{HandleGroup.PercentComplete}");}}

如果你想进一步了解他们,下面的UML展示了他们是如何工作的

UML

        他被分成了两部分,绿色节点主要用来统计进度,灰色节点主要用来桥接不同管线的资源,绿色的节点通过访问一个全局静态的GameObject实现了在不需要MonoBehaviour的情况下投递协程作业。

核心代码示例
//> XGlobalCoroutine.cs
//> Create by UniMarkusing System.Collections;
using UnityEngine;namespace XF.Internal
{internal class XGlobalCoroutine : MonoBehaviour {internal static XGlobalCoroutine Behaviour;public static XGlobalCoroutine Instance{get{if (Behaviour == null){GameObject root = new GameObject($"[Global]{typeof(XGlobalCoroutine).Name}");GameObject.DontDestroyOnLoad(root);Behaviour = root.AddComponent<XGlobalCoroutine>();}return Behaviour;}}}internal static class XAsyncOperationExtends {internal static void StartCoroutine(this XAsyncOperation operation, IEnumerator routine){if (routine == null) return;XGlobalCoroutine.Instance.StartCoroutine(routine);}internal static void StopCoroutine(this XAsyncOperation operation, IEnumerator routine){if (routine == null) return;XGlobalCoroutine.Instance.StopCoroutine(routine);}}
}
//> XAsyncOperation.Implement.cs
//> Create by UniMarkusing System;
using System.Collections;namespace XF
{/// <summary>/// 异步操作的抽象类/// </summary>public abstract class XAsyncOperation : IEnumerator{/// <summary>/// 是否完成/// </summary>public bool IsComplete { get; private set; }/// <summary>/// 完成百分比,取值[0~1]/// </summary>public virtual float PercentComplete { get; protected set; }/// <summary>/// 期间发生的错误信息,如果没有返回string.empty/// </summary>public string Error { get; internal set; }/// <summary>/// 完成时调用的回调/// 在完成前注册的回调会在完成时统一调用一次/// 在完成后注册的回调会在注册时立即执行一次/// </summary> public virtual event Action<XAsyncOperation> OnCompleted{add{if (IsComplete)value?.Invoke(this);elseCompletedEvent += value;}remove{CompletedEvent -= value;}}protected Action<XAsyncOperation> CompletedEvent;protected virtual void SetComplete(){IsComplete = true;PercentComplete = 1;CompletedEvent?.Invoke(this);CompletedEvent = null;}public virtual void Release() { }#region 接口 object IEnumerator.Current => null; bool IEnumerator.MoveNext() => !IsComplete; void IEnumerator.Reset() { }#endregion}
}
完整代码示例

unity_custom_async_operation

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

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

相关文章

算法之递归算法

递归是非常常见的一种算法&#xff0c; 也比较难以理解&#xff0c;简而言之&#xff0c;递归就是写了一个方法&#xff0c;方法中还调用了该方法&#xff0c;相当于自己调用自己&#xff0c;如果书写不当&#xff0c;就会有堆栈溢出的风险&#xff0c;无法跳出。 所以我们编写…

内网对抗-隧道技术篇防火墙组策略HTTP反向SSH转发出网穿透CrossC2解决方案

知识点&#xff1a; 1、C2/C2上线-CrossC2插件-多系统平台支持 2、隧道技术篇-应用层-SSH协议-判断&封装&建立&穿透 3、隧道技术篇-应用层-HTTP协议-判断&封装&建立&穿透隧道技术主要解决网络通讯问题&#xff1a;遇到防火墙就用隧道技术&#xff0c;…

深入分析 Android ContentProvider (五)

文章目录 深入分析 Android ContentProvider (五)ContentProvider 的性能优化和实践案例1. 性能优化技巧1.1. 数据库索引优化示例&#xff1a;添加索引 1.2. 批量操作与事务管理示例&#xff1a;批量插入操作 1.3. 使用异步操作示例&#xff1a;使用 AsyncTask 进行异步查询 1.…

手持式气象检测设备:便携科技,气象探测

一、手持式气象检测设备&#xff1a;小巧身躯&#xff0c;大能量 手持式气象检测设备&#xff0c;顾名思义&#xff0c;是一种可以手持操作的气象监测工具。它集成了温度、湿度、气压、风速风向等多种传感器&#xff0c;能够实时获取气象数据&#xff0c;并通过显示屏或手机APP…

如何快速抓取小红书帖子评论?两大实战Python技巧揭秘

摘要&#xff1a; 本文将深入探讨两种高效的Python方法&#xff0c;助您迅速获取小红书文章下方的所有评论&#xff0c;提升市场分析与用户洞察力。通过实战示例与详细解析&#xff0c;让您轻松掌握数据抓取技巧&#xff0c;为您的内容营销策略提供有力支持。 如何快速抓取小…

上传项目到GitHub

上传项目到GitHub 前期工作&#xff1a;创建GitHub仓库 1.使用git命令初始化文件夹 git init2.将文件夹里面所有的文件添加到本地仓库&#xff0c;如果想添加单个文件&#xff0c;将.换成文件名就好。 git add .3.给文件备注&#xff0c;双引号里面是文件备注的内容 git c…

监控系列(八)部署dameng_exporter并对接prometheus

一、下载dameng_exporter采集器 官网地址&#xff1a;https://github.com/gaoyuan98/dameng_exporter DM数据库适配prometheus监控的采集器&#xff0c;目前已支持DM8数据库同时提供grafana 8.5.X 以上版本的监控面板&#xff08;其他的grafana版本需要自己绘制表盘&#xff…

Nginx 如何处理 WebSocket 连接?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 Nginx 如何处理 WebSocket 连接&#xff1f;一、WebSocket 连接简介二、Nginx 处理 WebSocket 连接的基本原理三、配置 Nginx 支持 WebSocket 连接四、Nginx 中的…

MATLAB基础:数据和变量

今天我们开始学习MATLAB基础知识 1、常用非运算符及其作用 1、“,” 作为程序运行的分隔符&#xff0c;起到分隔语句的作用 2、“;” 同样作为分隔符&#xff0c;与“,”不同的是“;”会在程序运行时隐藏该行语句 如下图&#xff1a; 3、“...” 三个英文句点表示续行符…

【SpringBoot教程:从入门到精通】掌握Springboot开发技巧和窍门(四)-Vue项目配置环境、导航栏

主要写前端页面&#xff0c;采用vue框架写页面的导航栏&#xff01;&#xff01;&#xff01; 文章目录 前言 Vue项目配置环境 安装依赖 创建菜单 总结 前言 主要写前端页面&#xff0c;采用vue框架写页面的导航栏&#xff01;&#xff01;&#xff01; Vue项目配置环境 安装…

{Spring Boot 原理篇} Spring Boot自动装配原理

SpringBootApplication 1&#xff0c;Spring Boot 应用启动&#xff0c;SpringBootApplication标注的类就是启动类&#xff0c;它去实现配置类中的Bean的自动装配 SpringBootApplication public class SpringbootRedis01Application {public static void main(String[] args)…

AvaloniaUI的学习

相关网站 github:https://github.com/AvaloniaUI/Avalonia 官方中文文档&#xff1a;https://docs.avaloniaui.net/zh-Hans/docs/welcome IDE选择 VS2022VSCodeRider 以上三种我都尝试过&#xff0c;体验Rider最好。VS2022的提示功能不好&#xff0c;VSCode太慢&#xff0c…

构建基于Spring Boot的SaaS应用

引言 在设计和实现SaaS系统时&#xff0c;安全性是至关重要的考虑因素。一个全面的安全策略不仅能保护系统免受恶意攻击&#xff0c;还能确保用户数据的机密性、完整性和可用性。本文将探讨在SaaS架构中实现数据加密、敏感信息保护以及应用安全的最佳实践和技术方案&#xff0…

前端知识笔记之HTML

1.标签元素与属性&#xff0c;注意事项 2.多级标签排序List&#xff0c;无顺序&#xff08;Ul&#xff09;和有顺序(Ol) 3.HTML页面结构 4.页面跳转&#xff0c;注意#是统一页面的跳转 5.图片、视频、音频 标签 6.前端表单与后端方法 数据接收的demo 7.常见表单项 8.注意日期类…

html+css 实现水波纹按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…

虚拟机配置RabbitMQ集群教程

RabbitMQ是常用的一款消息中间件&#xff0c;那么如何在我们虚拟机中创建其集群呢&#xff1f;跟着博主这篇文章让你一步到位 本篇搭建的是三台机器为一个集群&#xff01;假设大家虚拟机都为初始化状态&#xff0c;从0开始&#xff08;注意集群搭建需要CentOS8以上环境&#x…

Wordpress安装到win10(2024年7月)

目录 1.wordpress介绍 2下载应用 2.1.wordpress 2.2XAMPP 2.3 PHPmyadmin 3.配置应用 3.1XAMPP进程 3.2 文件配置 3.3 phpmyadmin配置 4.配置网页 4.1 数据库创建 4.2 安装wordpress 5.进入面板 6.总结 1.wordpress介绍 WordPress是一个开源内容管理系统&#xff0…

新校区,新视野——广州六中以太彩光打造智慧教育新高地

广州市第六中学总务处 林继青 广州市第六中学是拥有85年办学历史的著名市重点中学,也是广东省首批一级学校和国家级示范性高中。作为广州市首批智慧校园建设示范单位,广州第六中学在从化、花都新建校区的智慧校园建设中“破旧立新”,让先进的以太全光技术与学校新校区建设同频共…

华为Ascend C算子开发(中级)考试

华为Ascend C算子开发&#xff08;中级&#xff09;考试题 提示&#xff1a;这个是河北廊坊Ascend C算子开发考试题和答案&#xff0c;仅供参考&#xff0c;因为不确定其他城市的考试题是否也是一样 文章目录 华为Ascend C算子开发&#xff08;中级&#xff09;考试题一、op_ho…

MySQL数据库练习(5)

1.建库建表 # 使用数据库 use mydb16_trigger;# 表格goods create table goods( gid char(8) primary key, name varchar(10), price decimal(8,2), num int);# 表格orders create table orders( oid int primary key auto_increment, gid char(10) not null, name varchar(10…