2018-10-04 19:13:49 u012632851 阅读数 526
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    2111 人正在学习 去看看 曾家海

环境:Unity2017.2 语言:C#

 

总起:

在使用协程的时候大家有没有遇到这样的问题?

 

因为协程之间可以相互嵌套,所以为了保证程序的清晰,便在其中添加了大量的嵌套代码,但是在想要停止协程的时候傻眼了,MonoBehaviour的StopCoroutine函数只能停止最外层的协程,如果正在执行里层的协程,必须等待里层的协程执行完毕(如果里层有while循环,那协程就永远不会停止了)。

 

以下是问题的代码:

private IEnumerator corDis;
void Awake()
{
    corDis = Cor1();
    StartCoroutine(corDis);
}

IEnumerator Cor1()
{
    Debug.Log(1);
    yield return new WaitForSeconds(2f);
    Debug.Log(2);
    yield return Cor11();
    Debug.Log(3);
    yield return new WaitForSeconds(4f);
    Debug.Log(4);
}

IEnumerator Cor11()
{
    Debug.Log(11);
    yield return new WaitForSeconds(2f);
    Debug.Log(22);
    this.StopCoroutine(corDis);
    Debug.Log(33);
    yield return new WaitForSeconds(4f);
    Debug.Log(44);
}

 

我们期望的是打印完33之后,程序就应该停止了,但是44仍会打印:

 

解决方案:

这边为MonoBehaviour添加了一个扩展方法,如下:

public static class UnityExtension
{
    public static void StopCoroutineNested(this MonoBehaviour mono, IEnumerator ie)
    {
        var cur = ie;
        mono.StopCoroutine(cur);
        while (cur.Current is IEnumerator)
        {
            cur = cur.Current as IEnumerator;
            mono.StopCoroutine(cur);
        }
    }
}

 

然后将this.StopCoroutine改为this.StopCoroutineNested就可以了:

 

这边有两个细节:

1.在使用扩展方法的时候,this不能省略;

2.停止的时候需要使用IEnumerator来停止,而不能使用Coroutine或者最原始的名称停止方式,因为无法获取到里层的协程。

 

当然大家完全可以自己实现一套协程的运行方式,所以的控制都在自己这边这类问题都是小事。但是总归在很多项目中,用了原始的协程,想要改成自己写的协程方式不仅工作量大、还需要和项目组做一些沟通,这个时候就可以使用上面的代码了。

2017-10-11 20:42:01 yuewei19 阅读数 160
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    2111 人正在学习 去看看 曾家海

协程介绍

Unity的协程系统是基于C#的一个简单而强大的接口 ,IEnumerator,它允许你为自己的集合类型编写枚举器。

yield return是“停止执行方法,并且在下一帧从这里重新开始”。

 

简单计时器实例:StartCoroutine()并没有给它传入参数,但是这个方法调用了它自己(这是通过传递CoroutineMethod的return返回值来实现的)

 

	// Use this for initialization
	void Start ()
	{
		StartCoroutine(CoroutineMethod()); 
	}
	
	IEnumerator CoroutineMethod ()
	{
		for (float timer = 3; timer >= 0; timer -= Time.deltaTime) {
			yield return 0;
		}
		Debug.Log ("This message appears after 3 seconds!");  
	}

 

hello实例:

 

	//This will say hello 5 times, once each frame for 5 frames
	IEnumerator 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;
		}
	}

 

 

 

开始和终止协程

 

		//If you start a Coroutine by name...  
		StartCoroutine("FirstTimer");  
		StartCoroutine("SecondTimer");  

		//You can stop it anytime by name!  
		StopCoroutine("FirstTimer");  

		//You can stop all anytime!
		StopAllCoroutines ();

 

2015-07-23 19:10:56 egostudio 阅读数 5624
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    2111 人正在学习 去看看 曾家海

使用

StartCoroutine(DoSomething());

开启协程,发现使用

StopCoroutine(DoSomething());

停止不了,看API原来是因为:

请注意只有StartCoroutine使用一个字符串方法名时才能用StopCoroutine停用之.

2018-04-08 11:38:11 pz789as 阅读数 632
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    2111 人正在学习 去看看 曾家海

在Unity里面有个很好用的东西,就是协程!

它可以很好的帮助我们做很多类似异步加载的东西,特别是资源多的时候,用的很频繁。而且,在一个协程之中,还可以嵌套很多小的协程,会让你用起来很舒服,思路很清晰。

但是,有时候需要停止加载,这里就出现问题了。因为经过尝试,Unity中的协程,只有两个方法可以停止协程,第一个是“StopCoroutine”,还有一个是停止所有的“StopAllCoroutines”。

他们都没法停止协程里面嵌套的协程,而且第一个停止只能停止带名称的方式协程

所以,我目前的做法是加入一个缓存,每个协程弄个标识,是否已经结束,然后在外部去控制他们删除。

2018-07-05 18:50:00 weixin_30367945 阅读数 4
  • Unity3D协程-基础篇

    本课程为Unity3D协程技术精讲中的基础部分,协程是UnityEngine技术里面为常用且设计为精髓的技术;基础部分主要讲解协成的前世今生,其中包括设计模式、实现模式、验证模式的递进式推进过程让同学们掌握协程原理与程序设计。

    2111 人正在学习 去看看 曾家海

我直接用StopCoroutine直接像StartCoroutine一样里面加方法不能停止该协程。通过把协程赋予到变量再控制此变量来停止才能中断此协程。

private IEnumerator cortinue;
cortinue = E_MoveToPoint();
 private IEnumerator  E_MoveToPoint()
 {
  
}
StopCoroutine(cortinue);

 

转载于:https://www.cnblogs.com/weiqiangwaideshijie/p/9269998.html

没有更多推荐了,返回首页