Unity中的模式——协同程序介绍
来源:互联网 发布:数据如何做韦恩图 编辑:程序博客网 时间:2024/05/29 16:02
原文:Introduction to Coroutines
Unity的系统程序系统的能力由C#的IEnumerator提供,IEnumerator是一个简单但是强大的接口,这个接口允许你写自己的可数集合类型。但是你不必在意这个,让我们直接跳到一个简单的例子,这个例子展示了协同程序可以做的事情。首先,让我们看一个简单的一小块代码:
The Countdown Timer
这里有一个简单的组件,组件仅仅减少它的timer字段,输出一个消息——timer到达了0。
using UnityEngine;using System.Collections; public class Countdown : MonoBehaviour{ public float timer = 3; void Update() { timer -= Time.deltaTime; if (timer <= 0) Debug.Log("Timer has finished!"); }}
不是太坏,非常少的代码达到了它的目标。但是有一个问题,如果我们有更多的组件(像一个Player或者Enemy类)它们有多个计时器,怎么办?我们的代码看起来就像这样:
using UnityEngine;using System.Collections; public class MultiTimer : MonoBehaviour{ public float firstTimer = 3; public float secondTimer = 2; public float thirdTimer = 1; void Update() { firstTimer -= Time.deltaTime; if (firstTimer <= 0) Debug.Log("First timer has finished!"); secondTimer -= Time.deltaTime; if (secondTimer <= 0) Debug.Log("Second timer has finished!"); thirdTimer -= Time.deltaTime; if (thirdTimer <= 0) Debug.Log("Third timer has finished!"); }}这也不算太坏,但是就个人而言,我不喜欢这些计时的变量让我的代码乱作一团。感觉很脏,我总是不得不确保在重新计时的时候重置它们(但是我经常忘记)。
如果我用for循环是否会变得好些?
for (float timer = 3; timer >= 0; timer -= Time.deltaTime){ //Just do nothing...}Debug.Log("This happens after 5 seconds!");这看起来很整齐,因为现在每一个计时的变量仅仅作为循环体的一部分,我不需要重复设置这些变量了。
好的,你可能了解了我大概的想法:协同程序可以将这件事做的很漂亮!
进入协同程序
现在,这里有一个和上边完全相同的例子,但是使用了一个协同程序!我建议你写一个简单的组件并且从现在开始跟着我的步骤,你自己再看看发生的事情。
using UnityEngine;using System.Collections; public class CoroutineCountdown : MonoBehaviour{ void Start() { StartCoroutine(Countdown()); } IEnumerator Countdown() { for (float timer = 3; timer >= 0; timer -= Time.deltaTime) yield return 0; Debug.Log("This message appears after 3 seconds!"); }}这里看起来有一点不同,我会解释这里发生了什么。
StartCoroutine(Countdown());这一行开始了我们的Countdown方法。注意我没有给Countdown传入一个引用,而是调用这个函数自身(有效的传递一个倒计时的值)
Yielding
这个Countdown函数能很好的自行解释他自己,除了两个部分:
*IEnumerator返回值
*for循环中的yield返回值
为了在多个帧中运行这个方法(这里指的是3秒内的帧),Unity通过某些方式已经存储了这个方法的状态。它使用IEnumerator类型代表yield return返回调用的值。当你yield一个方法的时候,就会说:“现在停止这个方法,在下一帧重新从这里开始执行!”
注意:yield 0或者null会告诉协同程序进入等待,直到下一帧继续之前。但是你也可以yield其他的协同程序,这个我会在一个课程中讲解。
一些例子
协同程序在一开始是相当让人困惑的,我看到新的和有经验的程序员在协同语法上都瞪大了他们的眼镜。所以,我会尽可能的通过例子来说明,这里有几个简单的协同程序的例子:
在一段时间里说“Hello”
记住,yield return 说:“停止这个函数,下一帧在继续执行”,这意味着可以做这些:
//This will say hello 5 times, once each frame for 5 framesIEnumerator SayHelloFiveTimes(){ yield return 0; Debug.Log("Hello"); yield return 0; Debug.Log("Hello"); yield return 0; Debug.Log("Hello"); yield return 0; Debug.Log("Hello"); yield return 0; Debug.Log("Hello");} //This will do the exact same thing as the above function!IEnumerator SayHello5Times(){ for (int i = 0; i < 5; i++) { Debug.Log("Hello"); yield return 0; }}永远的....在每一帧说“Hello”
在while循环里使用yield,你可以有一个持续运行的协同程序!这让你模拟在Update()循环中。
//Once started, this will run until manually stopped or the object is destroyedIEnumerator SayHelloEveryFrame(){ while (true) { //1. Say hello Debug.Log("Hello"); //2. Wait until next frame yield return 0; } //3. This is a forever-loop, goto 1}
...但是不像在Update()里,你可以协同程序里做一些花哨的事情,像这样:
IEnumerator CountSeconds(){ int seconds = 0; while (true) { for (float timer = 0; timer < 1; timer += Time.deltaTime) yield return 0; seconds++; Debug.Log(seconds + " seconds have passed since the Coroutine started."); }}这个函数的让协同程序亮了:这个函数的状态被存了起来,所以在函数体中任何定义的变量都会保持他们的值,甚至在两个帧之间。还记得在教程一开始的令人讨厌的计时变量吗?使用协同函数,我们不再需要他们,我们只需要在函数体中放置这些变量!
开始&&停止&&协同程序
之前,我们学习了通过调用StartCoroutine()方法启动一个协同程序,像这样:
StartCoroutine(Countdown());如果我们想要停止所有的协同程序,我们可以使用StopAllCoroutines()函数,它做的就像它的名字中承诺的一样。注意它只会停止这些协同程序——被该物体启动的协同程序,而不是其他MonoBehaviours运行的协同函数。
但是,如果我们有两个协同程序在运行会怎样,像这样:
StartCoroutine(FirstTimer());StartCoroutine(SecondTimer());...我们想要停止他们中的一个,怎么办?这种情况是不行的。如果我们想要停止一个特定的协同程序,你必须使用一个string为参数的函数,像这样:
//If you start a Coroutine by name...StartCoroutine("FirstTimer");StartCoroutine("SecondTimer"); //You can stop it anytime by name!StopCoroutine("FirstTimer");
额外的链接:
- Coroutines – Unity Script Referencee
0 0
- Unity中的模式——协同程序介绍
- Unity中的协同程序
- Lua中的协同程序——coroutine
- unity协同程序
- unity IEnumerator 协同程序
- Unity Coroutine协同程序
- Unity协同程序
- unity之协同程序
- Unity StartCoroutine 协同程序
- Unity-协同程序
- Unity中的协同函数
- Unity中的协同与线程
- Lua中的协同程序
- lua中的协同程序
- lua中的协同程序
- unity 协同程序有多线程效果
- 关于Unity协同程序的全面解析
- Unity协同程序(Coroutine)的解析
- .Net知识点(基础加强)
- RGB图像归一化
- 使用SVN对GitHub进行版本管理
- Lala Land and Apple Trees
- Reverse Integer
- Unity中的模式——协同程序介绍
- 矩阵内存排布
- Android WebView页面加载优化
- COJ 1011: Counting Pixels 暴力不解决问题
- CentOS之VI编辑器的常用命令
- LeetCode 231 Power of Two
- jeecg项目源码maven工程搭建
- 大数据的经济效益
- 题目1196:成绩排序