0
点赞
收藏
分享

微信扫一扫

【51单片机入门记录】RTC(实时时钟)-DS1302概述

AbrahamW 04-07 11:30 阅读 0

文章目录


什么是协程

A coroutine alows vou to spreacwhere it left off on the following anc return control toolinencoeframe.
协程允许您将任务分布在多个帧中。在 Unity 中,协程是一种方法可以暂停执行并将控制权返回给 Unity,然后在下一帧中从中断的地方继续。

In most situations,whenyou cal a method,it runs to completion and then retumns control to the caling method,plus any optional return vales.This means that any acion that takes place within amethod must happen within a single frame update.
在大多数情况下,调用方法时,它会运行到完成,然后将控制权返回给调用方法以及任何可选的返回值。这意味着在方法中发生的任何操作都必须在单个帧更新中发生。

n situations where you would like to use a method cal to contain a procedural animation or a seauence of events over time. you can use a coroutine如果希望使用方法调用来包含过程动画或随时间推移的事件序列,则可以使用协程

Howelver its imporeant to rememoerthat coroutines arent threads. Sinchronous operations thatrun within a coroutine stlexecute on the main thread.f you wantorecucethe amountof CpUtimespent on the mainthread,i’sjust as important to avoid blocking perations in coroutines as in any other secript code.fyouwanto use mult;threaded codewithin Uhiy, consider the C# Job System.但是,重要的是要记住协程不是线程。在协程中运行的同步操作仍在主线程上执行。如果要减少在主线程上花费的 CPU 时间,避免在协程中阳塞操作与在任何其他脚本代码中一样重要。如果要在 uniy 中使用多线程代码,请考虑 C# 作业系统,

It’s best to use coroutines if you need to deal with long asynchronous operations, such as waiing for HTTP transfers, asset loads,or file l/0 to complete如果需要处理长时间的异步操作,例如等待 HTTP 传输、资产加载或文件 V/0 完成,最好使用协程。

简单来说
协程,即为协同程序. Unity中的协程由协程函数和协程调度器两部分构成.协程函数使用的是C#的迭代器, 协程调度器则利用了MonoBehaviour中的生命周期函数来实现. 协程函数实现了分步, 协程调度器实现了分时.

注:因为协程分时分步执行的特性,当多个协程的耗时操作挤在同一时间执行也会造成卡顿。


协程的应用 - IEnumerator

我们先建立一个cube一段C#代码一起放进新创建的空件 EP18_01_Delay call

在这里插入图片描述
代码具体如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EP18_01_Delaycall : MonoBehaviour
{
    public GameObject cubeGo;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(DelayInstantiate());//正常方法是不会等协程的
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    //
    IEnumerator DelayInstantiate()
    {
        Debug.Log("协程开始了");
        yield return new WaitForSeconds(3);//等待3秒
        //yield return 0;//数字0没有意义,多少都一样,都是等待一帧
        Instantiate(cubeGo);
    }
}

在保存好源码后运行,等待3秒后就会在场景中原位置克隆一个新的cube
但是这样是不是还没法理解协程的意义

我们先利用一个新的方法名Test,验证一般情况下整个场景的运行情况

    void Start()
    {
        Debug.Log(1);
        Debug.Log(2);
        Test(0);//调用方法
   
    }
    private void Test(int num)
    {
        Debug.Log(num);
    }

它几乎第一时间就把这些信息都打印出来了
在这里插入图片描述
但是换成协程试试

    void Start()
    {
        StartCoroutine(DelayInstantiate());//正常方法是不会等协程的
        Debug.Log(1);
        Debug.Log(2);
        Test(0);//调用方法
    }
        IEnumerator DelayInstantiate()
    {
        Debug.Log("协程开始了");
        yield return new WaitForSeconds(3);//等待3秒
        //yield return 0;//数字没有意义,都是等待一帧
        Debug.Log(3);
        Instantiate(cubeGo);
    }


明明是最早的语句,但是3秒后才打印出来(这里差4秒是因为毫秒的存在)
在这里插入图片描述

这样看过来,我们还能意识到一点,就是在携程运行时,主程序不会等待写成程序运行完后在进行,而是一起进行,所以我们可以看成写成程序是一种分支运行方法,不影响主程序进程

如何控制协程的暂停

有的时候,我们在游戏过程中,可能因为一些原因需要停止并关闭掉一些正在运行流程,这种方法在C#中有两种常用的方法

第一种方法是用方法名的字符串形式,在Updata里通过某种操作(笔者通过按下S键)来停止

    void Start()
    {
        StartCoroutine("DelayInstantiate");//以字符串名的形式运行
        Debug.Log(1);
        Debug.Log(2);
        Test(0);//调用方法
    }
	void Update()
    {
        if(Input.GetKeyDown(KeyCode.S))//按下S时
        {
            //StopAllCoroutines();//停止整个协程
            StopCoroutine("DelayInstantiate");
        }
    }

第二种方法不用协程方法名的字符串,直接用其本身,不同的是需要定义一个程序内部的全局变量,通过这个变量作为媒介联系协程

    private Coroutine coroutine;//内部全局变量
	void Start()
    {
        coroutine = StartCoroutine(DelayInstantiate());
        Debug.Log(1);
        Debug.Log(2);
        Test(0);//调用方法
    }
	void Update()
    {
        if(Input.GetKeyDown(KeyCode.S))//按下S时
        {
            //StopAllCoroutines();//停止整个协程
            StopCoroutine(coroutine);
        }
    }


协程的另一种写法 - Invoke

这里我们新创建一个方法用来克隆立方体,然后利用Invoke来进行协程

    void Start()
    {
       Invoke("InstantantiateCube",3);//3意味着3秒后运行方法
    }
    private void InstantantiateCube()
    {
        Instantiate(cubeGo);
    }

最后也是成功克隆(这里将克隆后的立方体进行了移动)
在这里插入图片描述
还有一种循环协程的方法

InvokeRepeating("InstantantiateCube", 3, 1);//1表示等3秒后第一个立方体克隆完后,每1秒后在克隆一次)

成功克隆(为了看得清楚,笔者进行了移动)
在这里插入图片描述


场景管理

我们先创建两个新的场景 test1test2,并在 test2 里创建一个立方体
在这里插入图片描述
然后调出右上角的场景管理器
在这里插入图片描述
全部添加进去
在这里插入图片描述
重新编辑一块代码如下,我们会发现在1秒后将原来默认的SampleScene场景变成了1号场景test1

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.SceneManagement;//场景的命名空间

public class EP18_02_ : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Invoke("LoadScene",2);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    private void LoadScene()
    {
        SceneManager.LoadScene(1);//加载第1个场景
    }
}

同理也是可以进行别的场景替换

举报

相关推荐

0 条评论