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

news2024/11/27 4:19:01

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;
    }
}

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

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

相关文章

APP架构设计_1.官方应用架构指南

1.官方应用架构指南 1.1架构的原则 应用架构定义了应用的各个部分之间的界限以及每个部分应承担的职责。谷歌建议按照以下原则设计应用架构。 分离关注点通过数据模型驱动界面单一数据源单向数据流 1.2谷歌推荐的应用架构 每个应用应至少有两个层&#xff1a; 界面层 - 在屏…

近视防控明星:蔡司小乐圆中期临床数据详解

近视防控明星&#xff1a;蔡司小乐圆中期临床数据详解 小乐圆镜片作为近视防控镜片里的明星产品&#xff0c;从22年5月上市以来防控效果就一直备受大家的关注。而最近中期临床试验的结果&#xff0c;给家长孩子吃了一颗定心丸。 本次实验中&#xff0c;240位受试者被随机分成三…

基于springboot框架的电影订票系统_wqc3k

TOC springboot611基于springboot框架的电影订票系统_wqc3k--论文 绪 论 1.1研究背景和意义 随着科学技术的不断发展&#xff0c;计算机现在已经成为了社会的必需品&#xff0c;人们通过网络可以获得海量的信息&#xff0c;这些信息可以和各行各业进行关联&#xff0c;电影…

你应该停止使用的 7 个已弃用的 Python 库

欢迎来到雲闪世界。升级您的 Python 工具包&#xff1a;发现 7 个应停止使用的过时库以及替代它们的功能。最近&#xff0c;我回顾了 Python 的新特性&#xff0c;发现每个版本都引入了创新&#xff0c;使我们的日常开发工作变得更加轻松。 这让我意识到科技是一门永无止境的艺…

8.21 QT

1.思维导图 2. 服务器端 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer>//服务器类 #include <QMessageBox> #include <QDebug> #include <QList> #include <QTcpSocket>QT_BEGIN_NAMESPACE names…

免费高画质提取PPT/Word/Excel中的图片工具

下载地址&#xff1a;https://pan.quark.cn/s/134ccc35b8a2 软件简介&#xff1a; 好不容易搞到一个几十上百MB的ppt&#xff0c;想导出里面的图片进行二次加工&#xff0c;却被ppt超低画质的图片另存为功能劝退&#xff0c;明知里面全是高清图片&#xff0c;走时却是两手空空…

【C++从练气到飞升】14---深入浅出继承

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书&#x1f389; 目录 ⛳️推荐 一、继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1 定义格式 1.2.2 继承方式和访问限定符…

重新认识AbstractQueuedSynchronizer

开篇之前&#xff0c;烦请诸位允许我附庸风雅一次。近期因诸事繁杂&#xff0c;心情颇低落&#xff0c;遂于喜马拉雅APP中收听《老子》一文。其中的第八十一章《结天道》一文于我感悟颇深&#xff1a;和大怨&#xff0c;必有余怨&#xff0c;报怨以德&#xff0c;焉可以为善&am…

C++,std::bind 详解

文章目录 1. 概述2. 基本用法2.1 使用占位符2.2 示例 3. 总结 1. 概述 std::bind 是 C11 引入的一个功能&#xff0c;它允许你将函数&#xff08;或成员函数、函数对象&#xff09;与其参数绑定&#xff0c;生成一个新的可调用对象。这个功能在需要将函数及其参数一起传递给其…

DNF攻略:护石符文体系辅助详解,VMOS云手机助攻核心玩法!

在DNF游戏中&#xff0c;护石符文系统是提升角色实力的重要部分。当前版本中&#xff0c;护石符文体系经过了优化&#xff0c;使得获取方式更加便捷。以下是护石符文体系的详细介绍&#xff0c;以及如何使用VMOS云手机来更高效地管理和利用这一系统。 一、护石符文体系简介 护…

HarmonyOS 地图服务:深度解析其丰富功能与精准导航实力

目录 前期准备打造个性化地图&#xff1a;聚焦创建地图功能导入Map Kit相关模块通过MapOptions初始化地图切换地图类型设置地图中心点及层级展示定位按钮展示比例尺指定地图的日间夜间模式 通过MapComponentController对象方法控制地图切换地图类型开启3D建筑图层在指定的持续时…

【安当产品应用案例100集】008-UKEY在工业自动化数据传输中应用

工业自动化中的数据传输是确保生产过程高效、稳定运行的关键环节。工业自动化系统中&#xff0c;一般会有一个远程的客户端&#xff0c;负责将各个传感器、控制器等设备产生的信息传递到服务端&#xff0c;以实现生产过程的自动化控制和监控。它对于提高生产效率、降低生产成本…

SQL Server 2017上服务端设置强制加密启用SSL

在数据库服务端设置&#xff0c;强制所有客户端使用 SSL&#xff0c;设置完后&#xff0c;后续客户端所有连接&#xff0c;都将以密文传送&#xff0c;不论客户端是否指定安全连接&#xff08;即EncryptTrue/False&#xff09; 一、服务端强制加密使用 SSL 1.在数据库服务器上…

C++ 模板进阶知识

目录 一. 非类型模板参数 与类型模板参数确认的区别 何时确认 确认方式 二. 模板的特化 1. 概念 2. 函数模板特化 3. 类模板特化 3.1 全特化 3.2 偏特化 (1). 部分特化 (2). 进一步限制 4. 实际应用 三. 模板分离编译 1. 概念 2. 模板的分离编译 3. 解决方法 四…

【学习笔记】STM32F407探索者HAL库开发(一)STM32F4资源概要

【学习笔记】STM32F407探索者HAL库开发&#xff08;一&#xff09;STM32F4资源概要 1 硬件资源2 STM32命名规则3 STM32数据手册3.1 数据手册各章节内容概要3.2 引脚分布3.3 引脚定义3.4 引脚定义表的具体说明 1 硬件资源 STM32F407ZGT6具体的 内部资源如表 资源数量资源数量内…

鸿蒙Harmony实战开发:Touchscreen驱动器件硬件接口使用实例

功能简介 Touchscreen驱动用于驱动触摸屏使其正常工作&#xff0c;该驱动主要完成如下工作&#xff1a;对触摸屏驱动IC进行上电、配置硬件管脚并初始化其状态、注册中断、配置通信接口&#xff08;I2C或SPI&#xff09;、设定Input相关配置、下载及更新固件等操作。 在HDF&am…

考试:数据库系统(01)

数据库系统 ◆数据&#xff1a;是数据库中存储的基本对象&#xff0c;是描述事物的符号记录。 数据的种类&#xff1a;文本、图形、图像、音频、视频、学生的档案记录、货物的运输 情况等。 ◆数据库DB: 是长期存储在计算机内、有组织的、可共享的大量数据的集合。 ◆数据库…

安恒信息总裁宋端智,辞职了!活捉一枚新鲜出炉的餐饮人!

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

雅菲奥朗 FinOps 认证培训:开启企业云财务管理转型之路

前言&#xff1a; 在当今快速变化的商业环境中&#xff0c;企业面临着前所未有的IT财务挑战。随着云计算和数字化转型的推进&#xff0c;传统的财务管理方式已经不能满足“企业上云”的需求。FinOps&#xff0c;即“云财务管理”应运而生&#xff0c;成为帮助企业实现IT财务流…

Compose TextField详解

首先明确Compose TextField的底层依赖是&#xff1a; TextField BasicTextField CoreTextField 相较于Text&#xff0c;TextField需要提供可输入的能力以及渲染效果动态更新的能力。 // CompositionLocals// If the text field is disabled or read-only, we should not d…