每日一句:要活在自己的热爱里,而不是别人的眼光里
目录
练习:物体本身白色,点击攻击按钮,物体变为红色,两秒后变为原来颜色
协程
概念理解:
·与方法一样,协程是一种程序组件
·相对一般方法而言,协程更为灵活,方法只有一个入口,而协程可以有多个入口点或出口点,可以用协程来实现任何的方法
·协程更适用于实现合作式多任务,迭代器、无线列表
·开始一个协程时,执行从被调用方法的起始处开始,然而接下来的每次协程被调用时,从协程返回的位置接着执行(协程的“超能力”:它可以暂停逻辑的执行,并将掌控权移交给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 手册