Unity—协程

每日一句:要活在自己的热爱里,而不是别人的眼光里

目录

协程

概念理解:

Unity协程实现主要组成

使用协程的注意事项

练习:物体本身白色,点击攻击按钮,物体变为红色,两秒后变为原来颜色

练习:让立方体沿指定路线移动+在路点处停两秒


协程

概念理解:

·与方法一样,协程是一种程序组件

·相对一般方法而言,协程更为灵活,方法只有一个入口,而协程可以有多个入口点或出口点,可以用协程来实现任何的方法

·协程更适用于实现合作式多任务,迭代器、无线列表

·开始一个协程时,执行从被调用方法的起始处开始,然而接下来的每次协程被调用时,从协程返回的位置接着执行(协程的“超能力”:它可以暂停逻辑的执行,并将掌控权移交给U3D引擎,但是之后它还可以继续开始执行余下的逻辑)

·协程是单线程的

·协程只能在继承自MonoBehavior的脚本中使用

Unity协程实现主要组成

·Ienumerator/ɪˈnjuːməreɪtə/接口,提供迭代

·yield return XXXX 指定下一次迭代入口

—WaitForxedUpdate            暂停协程直到下一次FixedUpdate时才会继续执行协程

适用于物理控制[在FixedUpdate后执行]

—null,0,WaitForSeconds     使协程等待指定时间后再继续执行

适合于分多帧完成一个任务

WaitForOfFrame                处理等待帧,结束再恢复执行的逻辑

作用:等所有的摄像机和GUI被渲染完成后,再恢复协程的执行

[在每帧结束后执行]

—WWW                                  用来提供的URL获取内容的工具类

适合于网络下载数据

StartCoroutine/ˈkəʊruːˌtiːn/ 开启协程

2个重载StartCoroutine(string methodName,object value)(一切类型都派生自object)

        StartCoroutine(string methodName)(因为value有个默认值null)

        StartCoroutine(IEnumerator routine)

StopCoroutine结束协程

使用协程的注意事项

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

·协程可以嵌套任意多层

·如果想让多个脚本访问一个协程,可以定义静态的协程

·协程不是多线程,它们运行在同一线程中,跟普通脚本一样

·如果你的程序需要进行大量的计算,那么可以考虑在一个随时间进行的协程中处理它们

·IEnumerator类型的方法不能带ref或out型的参数

void OnGUI()

{if(GUILayout.Button(“开始计时”))

   StartCoroutine(TimeFunc(3));}

private IEnumerator TimeFunc(float timeCount)

{ yield return new WaitForSeconds(timeCount);

  print(timeCount+“秒时间到”);}

public class CoroutineDemo : MonoBehaviour

{ //获取当前正在运行协程的引用

    IEnumerator currentMoveCoroutine;

    //每按下空格时,会随机选择一个新的目的地并移动物体

private void Update()

    {

        if(Input.GetKeyDown(KeyCode.Space))

        { //如果当前有正在运行的协程,就停止该协程

            if (currentMoveCoroutine != null)

                StopCoroutine(currentMoveCoroutine);

            currentMoveCoroutine = Move(Random.onUnitSphere * 5, 8);

            StartCoroutine(currentMoveCoroutine);

        }

}

//创建一个协程,获取一个三维向量作为目标向量,一个浮点型作为速率

    IEnumerator Move(Vector3 destination,float speed)

    {

        while(transform.position!=destination)

        {

            transform.position = Vector3.MoveTowards(transform.position, destination,

                speed * Time.deltaTime一帧内物体能移到的距离);

            yield return null;或yield return new WaitForFixedUpdate();

【暂缓一帧执行(不让一帧过去要一点点移动)】

【移动到某个位置,不是一次,而是分多次,适宜用执行】

        }

    }

}

练习:物体本身白色,点击攻击按钮,物体变为红色,两秒后变为原来颜色

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

/// <summary>

/// 点击攻击按钮,物体变为红色,2秒后,变为白色

/// </summary>

public class Staycolordemo : MonoBehaviour

{

    //public  Color color;

    private Color oldcolor;

    private Renderer render;

    private void Start()

    {

        //color = GetComponent<Renderer>().material.color;

        render = GetComponent<Renderer>();

        oldcolor = render.material.color;

    }

    private void OnGUI()

    {

        if (GUILayout.Button("攻击"))

            StartCoroutine(ChangeColor());



    }

    private IEnumerator ChangeColor()

    {

        //color = Color.red;

        render.material.color = Color.red;

        yield return new WaitForSeconds(2);

        render.material.color = oldcolor;

    }

}

练习:让立方体沿指定路线移动+在路点处停两秒

using System.Collections;

using System.Collections.Generic;

using UnityEngine;



public class PathDemo : MonoBehaviour

{

    public Transform[] path;

    void Start()

    {

        StartCoroutine(FollowPath());

    }

    IEnumerator FollowPath()

    {

        foreach(Transform waypoint in path)

        {【等待至对方协程结束后在继续执行//协程的嵌套】

            yield return StartCoroutine(Move(waypoint.position, 6));

            yield return new WaitForSeconds(2);

          

        }

    }

    IEnumerator Move(Vector3 destination, float speed)

    {

        while (transform.position != destination)

        {

            transform.position = Vector3.MoveTowards(transform.position, destination,

                speed * Time.deltaTime);

            yield return null;

        }

    }

}

协程 - Unity 手册

猜你喜欢

转载自blog.csdn.net/m0_63330263/article/details/126324455