协程函数的返回值是IEnumerator,它是一个迭代器,可以把它当成执行一个序列的某个节点的指针。
首先将几个yield instructions的用法列出来:
1>WaitForSeconds(任意数字)
——等待对应秒数后执行后面的代码
——受timeScale影响
2>WaitForSecondsRealtime(任意数字)
——等待对应秒数后执行后面的代码
——不受timeScale影响
3>WaitForEndOfFrame()
——等待这一帧所有代码执行完成后执行后面的代码
4>WaitForEndOfFixedUpdate()
——等待FixedUpdate()中代码运行完成后执行后面的代码
yield return null/yield return 0
——等到Update()中代码运行完成后执行后面的代码
tips:协程需要用IEnumerator(迭代器)命名,其中必须包含yield return关键词
生命周期:
Start()-->FixedUpdate()-->WaitForFixedUpdate-->Update-->yield null-->WaitForSeconds/WaitForSecondsRealtime-->WaitForEndOfFrame
且协程是在Update和LateUpdate之间进行执行的,使用协程充分对脚本的生命周期进行合理的利用,可以使Update函数变得不那么庞杂。
下面分享一个用协程实现角色冲刺的方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
public float dashingPower = 20f;//冲刺的力度
public float dashingTime = 0.1f;//冲刺持续的时间
public float noDashTime = 1f;//冲刺的冷却时间
public bool canDash = true;//是否可以实现冲刺
private bool isDashing;//正在冲刺中
void Update()
{
if(isDashing)
{
return;
}
//当正在冲刺时后面所有操作都不能执行
if (Input.GetKeyDown(KeyCode.LeftShift) && canDash)
{
StartCoroutine(Dash());//用协程调用方法
}
}
private IEnumerator Dash()
{
canDash = false;//正在冲刺中,将状态改为不能冲刺
isDashing = true;//正在冲刺中
float dashingGravity = rb.gravityScale;
rb.gravityScale = 0f;//冲刺时重力为零,所以先获取rb的重力组件,并将其改为0
rb.velocity = new Vector2(transform.localScale.x * dashingPower, 0f);//冲刺的速度
yield return new WaitForSeconds(dashingTime);//冲刺时等待dashingTime的时间后执行后面程序
rb.gravityScale = dashingGravity;//冲刺完成,将重力恢复
isDashing = false;//将正在冲刺状态关掉
yield return new WaitForSeconds(noDashTime);//等待noDashTime的冷却时间后可以使用下次冲刺
canDash = true;//最后状态改为可以冲刺
}
}