unity之协同程序


          概念:在脚本执行过程中,有时会执行一些其他地方的代码,这时我们可以使用协程来处理。协同程序相当于一个代码片段。普通程序是自上而下依次执行,协同程序不是按顺序执行的。如下图:

unity之协同程序_第1张图片

任务3执行与否是不会影响任务4的执行。


在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在MonoBehaviour或继承于MonoBehaviour的类中调用。

 协同程序的返回类型为Coroutine类型。在Unity3D中,Coroutine类继承于YieldInstruction,所以,协同程序的返回类型只能为null、等待的帧数(frame)以及等待的时间。


这是unity官网ScriptAPI关于协同程序的描述:

using UnityEngine;
using System.Collections;

// In this example we show how to invoke a coroutine and continue executing
// the function in parallel.

public class ExampleClass : MonoBehaviour
{
    // In this example we show how to invoke a coroutine and
    // continue executing the function in parallel.

    private IEnumerator coroutine;

    void Start()
    {
        // - After 0 seconds, prints "Starting 0.0"
        // - After 0 seconds, prints "Before WaitAndPrint Finishes 0.0"
        // - After 2 seconds, prints "WaitAndPrint 2.0"
        print("Starting " + Time.time);

        // Start function WaitAndPrint as a coroutine.

        coroutine = WaitAndPrint(2.0f);
        StartCoroutine(coroutine);

        print("Before WaitAndPrint Finishes " + Time.time);
    }

    // every 2 seconds perform the print()
    private IEnumerator WaitAndPrint(float waitTime)
    {
        while (true)
        {
            yield return new WaitForSeconds(waitTime);
            print("WaitAndPrint " + Time.time);
        }
    }
    /* yield return是连在一起使用,new后面的内容是实例化一个对象,等待多少秒后继续执行。
     * 也可以不用中间变量coroutine,在start方法中的两个print方法,是在游戏加载的时候就执行了,所以等待时间是0秒,
     * 当执行 StartCoroutine(WaitAndPrint(2.0f))方法时,它会进入方法的内部while循环处,执行WaitForSeconds方法,并且每隔waitTime秒之后
     * 执行print方法。程序每隔2秒打印输出WaitAndPrint2 4 6 8不等。
     * 不能交换yield和print的顺序yield是等待多少秒之后,继续执行print方法。还有StartCoroutine是开启协同程序。参数是协同程序名
     */
}

   汉字部分是我自己的一些理解。


协程实现简单上下摆动动画:

代码:

 void Start()
    {
        m_Transform = gameObject.GetComponent();
        son_Transform = m_Transform.FindChild("smashing_spikes_b").GetComponent();

        normalPos = son_Transform.position;
        targetPos = son_Transform.position + new Vector3(0, 0.6f, 0);

        StartCoroutine("UpAndDown");
    }




    private IEnumerator UpAndDown()
    {
        //从游戏一开始就不断进行动画播放,因为这是一个死循环。。。
        while (true)
        {
            StopCoroutine("Down");
            StartCoroutine("Up");
            yield return new WaitForSeconds(2.0f);
            StopCoroutine("Up");
            StartCoroutine("Down");
            yield return new WaitForSeconds(2.0f);   
            
        }
    }


    private IEnumerator Up()
    {
        while (true)
        {
            //使用插值是让上升动画缓慢,如果直接使用son_Transform.position = target.position会一下子就上升了。
            son_Transform.position = Vector3.Lerp(son_Transform.position, targetPos, Time.deltaTime * 25);
            yield return null;
        }
    }

    private IEnumerator Down()
    {
        while (true)
        {
            son_Transform.position = Vector3.Lerp(son_Transform.position, normalPos, Time.deltaTime * 25);
            yield return null;
        }
    }
}
在start中调用开启系统程序,因为在update中是每帧调用一次。在上升下降动画是死循环调用--不停上下移动,所以在start中调用一次后,并没有结束,一直在调用上升下降。

你可能感兴趣的:(Unity,Game,Developing)