当前位置: 首页 > news >正文

2、Unity【基础】Mono中的重要内容

Unity基础 MonoBehavior中的重要内容

在这里插入图片描述

在这里插入图片描述

文章目录

  • Mono中的重要内容
    • 1、延迟函数
      • 1、延迟函数概念
      • 2、延迟函数使用
      • 3、延迟函数受对象失活销毁影响
      • 思考1 利用延时函数实现计时器
      • 思考2 延时销毁
    • 2、协同程序
      • 1、Unity是否支持多线程
      • 2、协同程序概念
      • 3、协同程序和线程的区别
      • 4、协程的使用
      • 5、yield return 不同内容的含义
      • 6、协程受对象和组件失活销毁的影响
      • 思考1 利用协程制作一个计时器
      • 思考2 利用协程创建十万立方体
    • 3、协同程序原理
      • 1、协程的本质
      • 2、协程的本体是迭代器方法的体现
      • 总结
      • 思考 通过迭代器自定义协程

Mono中的重要内容

1、延迟函数

1、延迟函数概念

延时执行的函数

2、延迟函数使用

只有继承MonoBehavior的脚本可以使用延时相关函数

1、延迟函数
Invoke();
参数一:函数名字符串
参数二:延迟时间 秒为单位注意:
1、Invoke只调用无参方法,若要调用有参,只需将有参方法写在无参方法体中
2、函数名必须是脚本上声明的函数
2、延迟重复执行函数
InvokeRepeating();
参数一:函数名字符串
参数二:第一次执行延迟时间
参数三:每次执行的间隔时间
3、取消延迟函数取消该脚本的所有延时函数CancelInvoke(); 指定函数名取消CancelInvoke("函数名");    
4、判断是否有延迟函数if(IsInvokeing()){print("存在延时函数");}if(IsInvokeing("函数名")){print("存在延时函数函数名");}

3、延迟函数受对象失活销毁影响

脚本依附对象失活or脚本失活
延时函数可以继续执行脚本依附对象销毁or脚本移除
延时函数无法继续执行void OnEnable(){//对象激活时,开启延迟
}
void OnDisable(){//对象失活时,停止延迟
}

思考1 利用延时函数实现计时器

方法一:

private int time = 0;
void Start()
{InvokeRepeating("DelayFunc",0,1);
}
void DelayFunc()
{print(time+"秒");time++;
}

方法二:

private int time = 0;
void Start()
{DelayFunc();
}
void DelayFunc()
{print(time + "秒");time++;Invoke("DelayFunc", 1);
}

思考2 延时销毁

void Start()
{//Destroy(gameObject,5);Invoke("DelayDes",5);
}
void DelayDes()
{Destroy(gameObject);
}

2、协同程序

1、Unity是否支持多线程

Unity是支持多线程的
只是新开线程无法访问Unity相关对象的内容
新开线程主要进行复杂逻辑运算或者网络消息接收等
注意:新开线程后Unity中的多线程要记得关闭Thread t;
void Start()
{t = new Thread(Test);t.Start();
}
void Test()
{while (true){Thread.Sleep(1000);print("Test");}
}
private void OnDestroy()
{t.Abort();t = null;
}

2、协同程序概念

1、协同程序简称协程:它是“假”的多线程,它不是多线程
2、它的主要作用:将代码分时执行,不卡主线程简单理解,是把可能会让主线程卡顿的耗时的逻辑分时分步执行
3、主要使用场景:异步加载文件异步下载文件场景异步加载批量创建时防止卡顿

3、协同程序和线程的区别

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

4、协程的使用

继承MonoBehavior的类都可以开启协程函数
第一步:声明协程函数
协程函数2个关键点1、返回值为IEnumerator类型及其子类2、函数中通过 yield return 返回值,进行返回
代码示例:    IEnumerator MyCoroutine(int i, string str){yield return new WaitForSeconds(5);}第二步:开启协程函数常用开后启方式StartCoroutine(MyCoroutine(1,"abc"));第三步:关闭协程关闭所有协程StopAllCoroutines();关闭指定协程Coroutine c = StartCoroutine(MyCoroutine(1,"abc"));StopCoroutine(c);

5、yield return 不同内容的含义

1.下一帧执行yield return 数字;yieldreturn null;在Update和LateUpdate之间执行2.等待指定秒后执行yield return new WaitForSeconds(秒);在Update和LateUpdate之间执行3.等待下一个固定物理顿更新时执行yield return new WaitForFixedUpdate();在FixedUpdate和碰撞检测相关承函数之后执行4.等待摄像机和GUI染完成后执行(用来截图)yield return new WaitForEndOfFrame(); 在LateUpdate之后的染相关处理完毕后之后5.一些特殊类型的对象 比如异步加载相关函数返回的对象
在之后【异步加载资源】【异步加载场景】【网络加载】里
一般在Update和LateUpdate之间执行6.跳出协程yield break;

6、协程受对象和组件失活销毁的影响

协程开启后
脚本组件和物体【销毁】,协程不执行
物体【失活】协程不执行
只有在脚本组件失活时协程执行

思考1 利用协程制作一个计时器

//开启协程
void Start()
{StartCoroutine(MyCoroutine());
}
//声明协程
IEnumerator MyCoroutine()
{int time = 0;while (true){print(time + "秒");time++;yield return new WaitForSeconds(1); }}

思考2 利用协程创建十万立方体

void Update()
{if (Input.GetKeyDown(KeyCode.Space)){StartCoroutine(CreateCube(10000));}
}
IEnumerator CreateCube(int num)
{for (int i = 0; i < num; i++){GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);cube.transform.position = new Vector3(Random.Range(-100, 100), Random.Range(-100, 100), Random.Range(-100, 100));if (i % 100 == 0){yield return null;}}
}

3、协同程序原理

1、协程的本质

协程可以分成两部分
1.协程函数本体
2.协程调度器协程本体就是一个能够中间暂停返回的函数
协程调度器是Unity内部实现的,会在对应的时机帮助我们继续执行协程函数Unity只实现了协程调度部分
协程的本体本质上就是一个C#的迭代器方法

2、协程的本体是迭代器方法的体现

1、协程函数本体
如果我们不通过开启协程方法执行协程
Unity的协程调度器是不会帮助我们管理协程函数的
但是我们可以自己执行迭代器函数内容void Start(){IEnumerator ie = Test(); //手动开启ie.MoveNext(); //得到第一个yield return前的内容print(ie.Current); //得到yield return的内容//循环获取内容while (ie.MoveNext())print(ie.Current);}IEnumerator Test(){print("第一次迭代内容");yield return "测试";}2.协程调度器
继承MonoBehavior后 开启协程
相当于是把一个协程函数(选代器)放入Unity的协程调度器中帮助我们管理进行执行
具体的yield return后面的规则也是Unity定义的一些规则总结
你可以简化理解迭代器函数
C#看到迭代器函数和yield return语法糖
就会把原本是一个的函数变成“几部分”!
我们可以通过迭代器从上到下遍历这“几部分”进行执行
就达到了将一个函数中的逻辑分时执行的目的而协程调度器就是利用送代器函数返回的内容来进行之后的处理
比如Unity中的协程调度器
限据yield return返回的内容决定了下一次在何时继续执行代器函数中的下一部分
理论上来说我们可以利用迭代器函数的特点自己实现协程调度器来取代unity自带的调度器

总结

协程的本质就是利用
C#的迭代器函数【分步】执行的特点加上
协程调度逻辑
实现的一套【分时】执行函数的规则

思考 通过迭代器自定义协程

请不使用Unity自带的协程协调器开启协程
通过迭代器函数实现每隔一秒执行函数中的一部分逻辑

CoroutineMgr

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class YieldReturnTime
{//每一次执行的迭代器接口public IEnumerator ie;//下一次执行的时间public float time;
}
public class CoroutineMgr : MonoBehaviour
{private static CoroutineMgr instance;public static CoroutineMgr Instance => instance;//声明用于存储迭代器对象的容器private List<YieldReturnTime> yrtList = new List<YieldReturnTime>();void Awake(){instance = this;}public void MyStartCoroutine(IEnumerator ie){//分步分时逻辑if (ie.MoveNext()){if (ie.Current is int){YieldReturnTime yrt = new YieldReturnTime();//记录迭代器和时间yrt.ie = ie;yrt.time = Time.time + (int)ie.Current;yrtList.Add(yrt);}}}void Update(){//判断预期时间,若正常时间>=预期时间,则执行下一步//倒着遍历,目的是防止遍历时迭代器移除内容发生前移,产生漏读for (int i = yrtList.Count - 1; i >= 0; i--){if (yrtList[i].time <= Time.time){if (yrtList[i].ie.MoveNext()){if (yrtList[i].ie.Current is int)yrtList[i].time = Time.time + (int)yrtList[i].ie.Current;}else{yrtList.RemoveAt(i);}}}}
}

Xiecheng

using System.Collections;
using UnityEngine;public class Xiecheng : MonoBehaviour
{void Start(){CoroutineMgr.Instance.MyStartCoroutine(MyCoroutine());}IEnumerator MyCoroutine(){print("A");yield return 1;print("B");yield return 1;print("C");yield return 1;print("D");yield return 1;}
}

相关文章:

2、Unity【基础】Mono中的重要内容

Unity基础 MonoBehavior中的重要内容 文章目录 Mono中的重要内容1、延迟函数1、延迟函数概念2、延迟函数使用3、延迟函数受对象失活销毁影响思考1 利用延时函数实现计时器思考2 延时销毁 2、协同程序1、Unity是否支持多线程2、协同程序概念3、协同程序和线程的区别4、协程的使用…...

C++11:右值引用、移动语义和完美转发

目录 前言 1. 左值引用和右值引用 2. 引用范围 3. 左值引用的缺陷 4. 右值引用的作用 5. 右值引用的深入场景 6. 完美转发 总结 前言 C11作为一次重大的更新&#xff0c;引入了许多革命性的特性&#xff0c;其中之一便是右值引用和移动语义。本文将深入探讨其中引入的…...

【大模型部署及其应用 】RAG检索技术和生成模型的应用程序架构:RAG 使用 Meta AI 的 Llama 3

目录 RAG检索技术和生成模型的应用程序架构1. **基本概念**2. **工作原理**3. **RAG的优势**4. **常见应用场景**5. **RAG的挑战**6. **技术实现**参考RAG 使用 Meta AI 的 Llama 3亲自尝试运行主笔记本与文档应用聊天关键架构组件1. 自定义知识库2. 分块3. 嵌入模型4. 矢量数据…...

python 速成指南

第一节. 过程式 python python 的一个特点是不通过大括号 {} 来划定代码块,而是通过缩进。如果和 C/C++ 类比的话,就是在左括号的地方不要换行,然后用一个冒号 (:) 替代, C/C++ 大括号内部的东西,缩进一个 tab 或者几个空格都可以(但需要保持一致),比如: if (x <…...

多重示例详细说明Eureka原理实践

Eureka原理&#xff08;Eureka Principle&#xff09;是指在长时间的思考和积累之后&#xff0c;通过偶然的瞬间获得灵感或发现解决问题的方法的一种认知现象。这个过程通常包括三个主要阶段&#xff1a;准备阶段、潜伏期以及突然的灵感爆发。下面详细说明Eureka原理的实践步骤…...

Qt下让程序只运行一个实例,避免重复打开

参考 【实现QT单例程序 QSystemSemaphore QSharedMemory】 做了一点点更改&#xff0c;主要是在openEuler上用时遇到的一点问题。 QSharedMemory *unimem nullptr; void checkExist() {QString memName "SingleApp"; // 注意这名字要每个工程不一样&#xff0c;否…...

考研交流平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示技术栈系统测试为什么选择我官方认证玩家&#xff0c;服务很多代码文档&#xff0c;百分百好评&#xff0c;战绩可查&#xff01;&#xff01;入职于互联网大厂&#xff0c;可以交流&#xff0c;共同进步。有保障的售后 代码参考数据库参…...

哈希表--有效的字母异位词

给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true示例 2: 输…...

GC终结标记 SuspendEE 是怎么回事

一&#xff1a;背景 1. 讲故事 写这篇是起源于训练营里有位朋友提到了一个问题&#xff0c;在 !t -special 输出中有一个 SuspendEE 字样&#xff0c;这个字样在 coreclr 中怎么弄的&#xff1f;输出如下&#xff1a; 0:000> !t -special ThreadCount: 3 UnstartedTh…...

Ubuntu 中GCC交叉编译工具链安装

​ Ubuntu 自带的 gcc 编译器是针对 X86 架构的&#xff0c;如果要编译的是 ARM 架构的代码&#xff0c;就需要一个在 X86 架构的 PC 上运行&#xff0c;可以编译 ARM 架 构代码的 GCC 编译器&#xff0c;这个编译器就叫做交叉编译器&#xff0c;总结一下交叉编译器就是&#x…...

JEXL(Java Expression Language)用法概览

JEXL&#xff08;Java Expression Language&#xff09;是一个用于在Java应用程序中解析和执行表达式的库。JEXL的设计目的是通过提供一种类似于脚本语言的语法&#xff0c;使得可以在应用程序中动态地计算表达式的值。JEXL常用于模板引擎、规则引擎和配置文件等场景。 下面介…...

NC 完全二叉树结点数

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一棵完全…...

点灯案例优化(二) 利用位运算修改特定位

前面&#xff0c;我们对点灯代码进行了第一次优化&#xff0c;效果如下 尽管第一次优化以后代码可读性确实高了不少&#xff0c;也看起来更加简洁&#xff0c;但是&#xff0c;这里仍旧存在一个很严重的问题&#xff1a;就在每一个表达式右边&#xff0c;我们给寄存器的数据赋值…...

【C++备忘录】

记录一些C比较好用的代码块&#xff0c;方便自个查看。 使用std::copy 快速打印序列 #include <iostream> #include <algorithm> #include <iterator>int main() {int a[5] { 1, 2, 3, 4, 5 };copy(begin(a), end(a), ostream_iterator<int>(cout, …...

java编程 斐波拉契数列算法集锦【斐波拉契数列】【下】【集合类】【Stream函数式编程】

斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列&#xff0c;是一个非常经典的递归问题。斐波那契数列的算法描述&#xff1a; 斐波那契数列&#xff0c;一个令人着迷而又充满神秘色彩的数字序列&#xff0c;它以0和1作为起始&#xff…...

智慧园区三维可视化平台

背景 随着物联网、人工智能等新一代信息技术的发展&#xff0c;数字孪生技术逐渐成为实现这一目标的关键工具。数字孪生技术能够对物理世界进行高精度、全要素的映射&#xff0c;并实时动态反映其变化情况&#xff0c;从而为园区提供精准的管理和服务。 方案简介 智慧园区数字…...

Redis 有序集合【实现排行榜】

使用 Redis 的 Sorted Set 数据结构可以非常高效地实现实时排行榜功能。Sorted Set 允许将元素按分数进行排序&#xff0c;同时支持插入、删除和查询操作&#xff0c;且这些操作的时间复杂度较低&#xff0c;非常适合处理高并发的场景。 实现思路 插入操作&#xff1a;当用户…...

ORACLE数据库管理系统介绍

1.ORACLE的特点: 可移植性 ORACLE采用C语言开发而成,故产品与硬件和操作系统具有很强的独立性。从大型机到微机上都可运行ORACLE的产品。可在UNIX、DOS、Windows等操作系统上运行。可兼容性 由于采用了国际标准的数据查询语言SQL,与IBM的SQL/DS、DB2等均兼容。并提供读取其它…...

C# 中Linq探讨 Or条件拼接

在C#中&#xff0c;没有直接内置于.NET Core或.NET Framework中的NuGet包能够直接“拼接”LINQ的OR条件&#xff0c;因为LINQ本身设计为一种声明式编程模型&#xff0c;用于查询数据集合。然而&#xff0c;你可以通过一些方式来实现多个条件以OR逻辑组合的效果&#xff0c;而不…...

有关应用层面试题有关库的思维导体

面试题目&#xff1a; TCP通信中3次握手和四次挥手&#xff1f; 答&#xff1a; 第一次握手&#xff1a;客户端发送SYN包&#xff08;SYN1, seq0&#xff09;给服务器&#xff0c;并进入SYN_SENT状态&#xff0c;等待服务器返回确认包。第二次握手&#xff1a;服务器接收到S…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...