Unity async/await Coroutinues
c# async / await工作流可以简化你的代码,让你在Unity中对游戏有更多的控制。
学习如何转换当前协程工作流、什么是任务、如何运行顺序和同步代码以及如何从异步函数返回数据。
例子:
我们要控制三个物体在同一时间旋转以及按顺序旋转
层级视图:
相同时间旋转时,异步代码如下
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
public static class MyExtension
{
public static void GetChilds(this Transform transform, List<Transform> objects)
{
for (int i = 0; i < transform.childCount; i++)
objects.Add(transform.GetChild(i));
}
}
public class AsyncManager : MonoBehaviour
{
private List<Transform> _objects = new List<Transform>();
private void Start()
{
transform.GetChilds(_objects);
for (int i = 0; i < transform.childCount; i++)
{
RotateObj(i);
}
}
private async void RotateObj(int index)
{
var end = Time.time + 1.5f;
while (end - Time.time > .0f)
{
_objects[index].Rotate(Vector3.forward * 90 * Time.deltaTime);
await Task.Yield();
}
}
}
按顺序旋转时,异步代码如下
private async void Start()
{
transform.GetChilds(_objects);
for (int i = 0; i < transform.childCount; i++)
{
await RotateObj(i); //等待任务执行完之后再继续执行
}
}
private async Task RotateObj(int index)
{
var end = Time.time + 1.5f;
while (end - Time.time > .0f)
{
_objects[index].Rotate(Vector3.forward * 90 * Time.deltaTime);
await Task.Yield();
}
}
相同时间旋转时,协程代码如下
private void Start()
{
transform.GetChilds(_objects);
for (int i = 0; i < transform.childCount; i++)
{
StartCoroutine(RotateObj(i));
}
}
private IEnumerator RotateObj(int index)
{
var end = Time.time + 1.5f;
while (end - Time.time > .0f)
{
_objects[index].Rotate(Vector3.forward * 90 * Time.deltaTime);
yield return null;
}
}
按顺序旋转时,协程代码像下面是的
private IEnumerator Action1()
{
yield return new WaitForSeconds(1);
}
private IEnumerator Action2()
{
yield return new WaitForSeconds(1);
}
private IEnumerator Action3()
{
yield return new WaitForSeconds(1);
}
private IEnumerator Sequeue()
{
yield return StartCoroutine(Action1());
yield return StartCoroutine(Action2());
yield return StartCoroutine(Action3());
}
因为太麻烦,我们就不再对按顺序旋转时,协程进行实现
扩展:
public class AsyncManager : MonoBehaviour
{
private List<Transform> _objects = new List<Transform>();
private Task[] _tasks = new Task[3];
private async void Start()
{
transform.GetChilds(_objects);
for (int i = 0; i < transform.childCount; i++)
{
_tasks[i] = RotateObj(i);
}
//当列表中所有任务执行完成之后才会继续往下执行
//代码执行顺序是对的,只是在碰上协程异步时会在刚进行时继续向下执行,因为他们并不在同一线程
await Task.WhenAll(_tasks);
Debug.Log(111);
}
private async Task RotateObj(int index)
{
var end = Time.time + 1.5f;
while (end - Time.time > .0f)
{
_objects[index].Rotate(Vector3.forward * 90 * Time.deltaTime);
await Task.Yield();
}
}
}