Unity里的协程Coroutines

Unity里的Coroutine在帮助我们实现序列化事件时尤其方便。可以让事件依次发生,可以让事件A等待事件B结束后才开始执行。

但需要厘清几个基本概念。

Coroutines不是多线程,不是异步技术。Coroutines都在MainThread中执行,且每个时刻只有一个Coroutine在执行。 Coroutine是一个function,可以部分地执行,当条件满足时,未来会被再次执行直到整个函数执行完毕。

A coroutine is a function that is executed partially and, presuming suitable conditions are met, will be resumed at some point in the future until its work is done.  (http://unitygems.com/coroutines/)

Unity在每一帧都会去处理GameObject里带有的Coroutine Function,直到CoroutineFunciton被执行完毕。

当一个Coroutine开始启动时,它会执行到遇到yield为止,遇到yieldCoroutine会暂停执行,直到满足yield语句的条件,会开始执行yield语句后面的内容,直到遇到下一个yield为止…… 如此循环,直到整个函数结束。

将函数分到多个帧里去执行,帅嘛!

http://unitygems.com/coroutines/ 这个网址里关于Coroutines的教程很好,强烈推荐好好读读。

一个Coroutines应用的小例子,动画播放到某个指定进度执行某些事情:

using UnityEngine;

using System.Collections;

public class DieSequence : MonoBehaviour {

// Use this for initialization

void Start () {

StartCoroutine(Die ());

}

//Wait for an animation to be a certain amount complete

IEnumerator WaitForAnimation(string name, float ratio, bool play)

{

//Get the animation state for the named animation

var anim = animation[name];

//Play the animation

if(play)

{

animation.Play(name);

animation[name].speed = 0.3f;

}

//Loop until the normalized time reports a value

//greater than our ratio.  This method of waiting for

//an animation accounts for the speed fluctuating as the

//animation is played.

while(anim.normalizedTime + float.Epsilon + Time.deltaTime < ratio)

yield return new WaitForEndOfFrame();

}

IEnumerator Die()

{

//Wait for the die animation to be 50% complete

yield return StartCoroutine(WaitForAnimation("anim_die005_360",0.5f, true));

//Drop the enemies on dying pickup. Do sth you need

Debug.Log("Half Death, Drop sth");

yield return StartCoroutine(WaitForAnimation("anim_die005_360",1f, false));

Debug.Log("Whole Anim Ended.");

Destroy(gameObject);

}

}

Coroutine里面套Coroutine: StartCoroutine(Die()), Die()里StartCoroutine(WaitForAnimation("anim_die005_360",0.5f, true)),

当Die()里WaitForAnimation的Coroutine完成后(即Animation的播放进度大于ratio了),yield return了,才能在接下来的Frame里,执行Die()后面的东东。

由于WaitForAnimation()里并没有PauseAnimation或者StopAnimation,所以其实Die()函数里没有 yield return StartCoroutine(WaitForAnimation("anim_die005_360",1f, false));这一行,动画也会播放完毕。这一句可以保证在动画播放完毕时去执行某些东东。

使用WaitForSeconds(float time)时需要注意,当Time.timeScale = 0f时,yield return new WaitForSeconds(t) (t>0)永远不会返回,即这行后面的rountine不会被执行到。

如果在游戏里游戏时间静止时,又想用WaitForSeconds类似的功能怎么办?

可以自己实现类似的功能。

例如:

IEnumerator CutSequence()

{

_runningSequence = true;

 Time.timeScale = 0;

var originalPosition = Camera.main.transform.position;

foreach(var ball in BallScript.allBalls.ToArray())

{

if (ball != null)

{

Vector3 targetPosition = ball.transform.position - Vector3.forward * 2f;

yield return StartCoroutine(MoveObject(Camera.main.transform, targetPosition, 2));

yield return WaitForRealSeconds(0.5f);

}

}

Coroutine WaitForRealSeconds(float time)

{

return StartCoroutine(Wait(time));

}

IEnumerator Wait(float time)

{

var current = Time.realtimeSinceStartup;

while(Time.realtimeSinceStartup - current < time)

{

yield return null;

}

}

Unity里的协程Coroutines

时间: 2024-10-12 15:44:51

Unity里的协程Coroutines的相关文章

Unity中的协程(一)

这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines   这篇文章转自:http://blog.csdn.net/huang9012/article/details/38492937 协程介绍 在Unity中,协程(Coroutines)的形式是我最喜欢的功能之一,几乎在所有的项目中,我都会使用它来控制运动,序列,以及对象的行为.在这个教程中,我将会说明协程是如何工作的,并且会附上一些例子来介绍它的用法

Python 协程 - Coroutines

1 协程 - Coroutines 2 3 Awaitable Objects, 4 Awaitable Objects 通常由 __await__() 生成, 而 5 Coroutine objects 是由 async def 关键字定义的函数 return 的 Awaitable Objects. 6 Note, 7 被 types.coroutine() or asyncio.coroutine() 装饰的生成器迭代器对象(generator iterator objects) 8 是没

Unity自己实现协程

自己实现协程有几个好处: 脱离Unity独立,拿到别的地方也可以用. 非主线程也可以启动协程,然后在主线程执行,比如异步网络消息等. 可以给每个协程一个id,通过id随时启动或关闭某个特定的协程,或者非MonoBehavior对象也可以管理属于自己的协程. Unity中,Coroutine是在LateUpdate执行的,每一个update都会执行一部分代码,拿IEnumerator来说,就是每一次都会MoveNext一下. IEnumerator有三个接口: Current:返回一个object

Unity中使用协程进行服务端数据验证手段

近期在做项目中的个人中心的一些事情,用户头像上传,下载,本地缓存,二级缓存,压缩,这些都要做,麻雀虽小五脏俱全啊,也是写的浑浑噩噩的, 当我们在上传用户头像的时候,向服务端发送上传头像请求之前,一般都会做一次验证,向服务端获取token验证信息,来确保非法上传,如果不做这个那么会有非法用户上传非法图像,使你的服务器 带来未知的灾难. 而验证的逻辑很好写,并没有什么难度,比如: Server.SendMessage("获取token"); Client.Receive(string to

unity里头的协程

1 IEnumerator ie = null; 2 3 void Start() 4 { 5 ie = coroutinFunc(); //这里只是新建了一个协程,并不会执行协程函数里的代码,需要调用StartCoroutine方法或者ie.MoveNex才会执行协程函数里的代码 6 } 7 8 IEnumerator coroutinFunc() 9 { 10 yield return 0; 11 } 在没有调用StartCoroutine方法来执行协程函数的时候,ie.MoveNext才会

【Unity】理解协程的原理1——实现一个自己的WaitForSeconds

协程的所能达到的效果就是在指定的时间点上执行需要执行的代码,Unity中开始一个协程的函数是StartCoroutine,而提供的延迟的类有以下几种分别是 new WaitForEndOfFrame; //等待一帧 new WaitForFixedUpdate; //等待一个FixedUpdate(固定时间间隔) new WaitForSeconds; //等待X秒 new WWW; //等待外部资源加载完毕 本文就针对其中的WaitForSeconds实现进行探究. 因为在开发过程中,很多时候

Unity中使用协程实现倒计时功能

unity中协程的功能很强大,能够充分发挥unity协程功能的地方就是游戏的倒计时,今天我们就来实现一个简易版本的倒计时. 新建一个场景,给camera添加一个脚本,脚本内容如下: using UnityEngine; using System.Collections; public class ShowNumber : MonoBehaviour { private int tmp = 10; // Use this for initialization void Start () { //开

【Unity笔记】协程Coroutine的简单优化

一个最简单的协程,也至少需要2帧才能完成.第一帧走到yield return null停止,第二帧从此处接着执行完下面的操作.需求:如果缓存中存在某数据则直接使用,否则联网异步下载. private bool cached; // 该数据是否已有缓存 void Start(){ StartCoroutine(Download()); } IEnumerator WorkWhenDownload() { if(cached){ // 直接使用缓存 }else{ // 没有缓存,联网下载 WWW w

Unity中的协程用法以及注意事项

前沿:这章节,将简单的总结一下如何开启协程,关闭协程,以及使用协程的注意事项. 一.如何开启协程: private void Start() { m_SpherePrefab = Resources.Load<GameObject>("Test/Sphere_00"); Debug.Log("m_SpherePrefab = " + m_SpherePrefab); #region 协程的学习及使用 StartCoroutine(Test_00());