Unity之协程

2022-09-10 10:30:44 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

老早就对Unity这个功能产生了强烈的好奇,今天就要把这块骨头给啃了。

目前我对协程的理解相当于有点像线程,但它实际上不是线程。话不多说先来个代码给个初印象:

一、开启协程:

我在Unity下创建了一个Cube(随便什么物体都行),然后把我的cs文件挂载上去。点击Unity上的开始按钮,运行:

代码如下:

代码语言:javascript复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestCoroutine : MonoBehaviour
{
    private GameObject cube;
    // Start is called before the first frame update
    void Start()
    {
        cube = GameObject.Find("Cube");
        Debug.Log(cube.transform.position);
        #region
        StartCoroutine(Test());
        #endregion

    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private IEnumerator Test()
    {
        
        Debug.Log(System.DateTime.Now " hello");
        yield return new WaitForSeconds(3f);
        Debug.Log(System.DateTime.Now " world");
    }
}

聪明的你看明白发生什么事情了吗?

1.首先我打印出了Cube的位置,这个没什么作用。就是想缓冲一下,让你看到程序进行到哪一步了。

2.然后开启了一个协程,这个协程函数是Test(),进入到Test()函数以后,首先打印出了当前系统时间 hello。

3.然后等待了3s,又打印出了当前系统时间 world。(我们也能算出来秒数增加了3s)

总结:yield return 相当于是“停止执行方法,并且下一帧从这里开始”。

我们上面的程序就相当于停止Test()方法,3s以后下一帧开始执行,输出world字符串

那么,联想一下,这个协程程序是否和Unity自带的Update()函数可以共通呢?我们来做个实验,把刚才的代码稍作修改:

代码语言:javascript复制
private IEnumerator Test()
    {
        
        Debug.Log(Time.time " hello");
        yield return new WaitForSeconds(0f);
        Debug.Log(Time.time " world");
    }

在Unity的Console面板上点击显示时间戳:

,(为什么不用之前的函数了,因为那个函数显示的时间不够精确)

聪明的你发现什么了吗?0.02是怎么出来的呢?

Time.time

这个属性是显示帧时。因为yield return是等待下一帧执行,而这里又等待了0s,所以我们从第一帧到下一帧开始用了0.02s,这也是默认的Unity每帧更新的时间:0.02s

不信的话,我们用Update()来验证一下(以下是疯狂打脸时间):

代码语言:javascript复制
void Update()
    {
        Debug.Log(Time.frameCount " " Time.time);
        
    }

挠头,由以上验证过程可以看出Update()每帧的时间并不是完全一样,那么怎么解释呢?

(参考博客:https://blog.csdn.net/book_longssl/article/details/40150839)

感谢博主给出了详细的解释,让我也明白了Update()和FixedUpdate()的区别。

二、停止协程

既然有开,那么就有关咯。话不多说,先上代码:

代码语言:javascript复制
void Update()
    {
        if (Input.GetKeyUp(KeyCode.Space))
        {
            StopCoroutine(Test());
            Debug.Log("已停止协程");
        }
        
    }

当然了,如果在程序中开始的协程是字符串形式,那么结束也应该是字符串形式:

有些注意事项:

1.多个协程可以同时运行,它们会根据各自的启动顺序来更新

2.协程不是线程,它们运行在同一线程中,跟普通的脚本一样。

3.目前Unity中没有简便的方法来检测作用于对象的协程数量以及具体是哪些协程作用在对象上。

emm,好像没什么要说的了。后续有什么想法再补充。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/151810.html原文链接:https://javaforall.cn

0 人点赞