Unity插件 Unitask学习日志
下载地址
https://github.com/Cysharp/UniTask
点击这里可以查阅中文文档
在Unity 2020,2021 中使用UPM下载会找不到,可以使用2022版本的unity可以在upm中找到。
安装方式:
下载zip之后解压,
复制Plugins
到Unity项目中即可。
Content
-
使用Unitask 的最低版本是:Unity 2018.4.13f1.
_ = DelayFrame_Test(100);
中的_=
在 丢弃 符号,不是没有意义的。用于忽略返回值的语法,通常用于那些不需要处理返回值的方法调用,但仍然希望调用该方法。 -
仅仅记录了github中文档的一小部分,文档的后面有“错误处理”,“超时处理”,“进度”,“线程切换” 等。详情请查阅github文档
-
写法是:
private async UniTask 方法名称
{
await 操作
}
private async UniTask<T> 方法名称
{
await 操作
retun 返回值
}
全部代码记录
using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
public class UnitaskTest : MonoBehaviour
{
public RotateCube goRotateCube;
void Start()
{
Debug.Log("进入start方法");
UniTask<string> ssst = DemoAsync();
_ = DelayFrame_Test(100);
_ = SendGetHttpRequest();
_ = WaitUnityPlayerLoop();
_ = ReplaceYield();
_ = WaitForEndOfFrame();
_ = WaitUntilCondition();
_ = WaitUntilValueChangedCondition();
_ = FooCoroutineEnumerator();
Debug.Log("start方法结束");
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.O))
{
goRotateCube.enabled = false;
}
if (Input.GetKeyDown(KeyCode.I))
{
goRotateCube.gameObject.transform.localPosition = new Vector3(1, 0, 0);
}
}
private async UniTask<string> DemoAsync()
{
Debug.Log("Unitask进入 异步");
var asset = await Resources.LoadAsync<TextAsset>("fulman");
for (int i = 0; i < 500; i++)
{
GameObject.CreatePrimitive(PrimitiveType.Capsule);
}
Debug.Log("Unitask异步读取文件,创建物体结束");
return (asset as TextAsset)?.text ?? throw new InvalidOperationException("Asset not found");
}
/// <summary>
/// 等待100帧
/// </summary>
/// <returns></returns>
private async UniTask DelayFrame_Test(int frameCount)
{
Debug.Log("等待100帧开始" + Time.frameCount);
// 等待一个基于帧的延时操作(就像一个协程一样)
await UniTask.DelayFrame(frameCount);
Debug.Log("等待100帧结束" + Time.frameCount);
}
/// <summary>
/// 异步发送http的get请求
/// </summary>
/// <returns></returns>
private async UniTask<string> SendGetHttpRequest()
{
Debug.Log("异步发送http的get请求开始");
string webText =
(await UnityWebRequest.Get
("https://github.com/Cysharp/UniTask/blob/master/README_CN.md")
.SendWebRequest()).downloadHandler.text;
Debug.Log("异步发送http的get请求结束" + webText);
return webText;
}
/// <summary>
/// 等待一个Unity的生命周期
/// </summary>
/// <returns></returns>
private async UniTask WaitUnityPlayerLoop()
{
Debug.Log("异步开始等待Unity的一个生命周期,LastInitialization");
await UniTask.Yield(PlayerLoopTiming.LastInitialization);
Debug.Log("异步结束等待Unity的一个生命周期,LastInitialization");
var go = GameObject.CreatePrimitive(PrimitiveType.Capsule);
go.transform.position = new Vector3(3, 0, 3);
}
/// <summary>
/// Yield的替代,
/// </summary>
/// <returns></returns>
private async UniTask ReplaceYield()
{
Debug.Log("UniTask.Yield当前帧数是start:" + Time.frameCount);
//等下一帧执行
await UniTask.Yield();
Debug.Log("UniTask.Yield之后的帧数是end:" + Time.frameCount);
Debug.Log("第二个开始");
Debug.Log("NextFrame当前帧数是start:" + Time.frameCount);
//等下一帧执行
await UniTask.NextFrame();
Debug.Log("NextFrame等待一帧之后end:" + Time.frameCount);
}
/// <summary>
/// 等待这帧结束后进行操作
/// </summary>
/// <returns></returns>
private async UniTask WaitForEndOfFrame()
{
Debug.Log("帧开始:" + Time.frameCount);
await UniTask.WaitForEndOfFrame(this);
Debug.Log("帧结束 :" + Time.frameCount);
}
/// <summary>
/// 某个条件满足的时候触发
/// </summary>
/// <returns></returns>
private async UniTask WaitUntilCondition()
{
Debug.Log("方块还在转圈");
// yield return WaitUntil 替代方案
//等待满足于某个条件的时候执行
await UniTask.WaitUntil(() => goRotateCube.enabled == false);
Debug.Log("方块不转圈啦!!!");
}
/// <summary>
/// 当某个值改变的时候触发
/// </summary>
/// <returns></returns>
private async UniTask WaitUntilValueChangedCondition()
{
Debug.Log("监听goRotateCube 是否改变位置");
//开始监听goRotateCube 的X是否 改变位置
await UniTask.WaitUntilValueChanged(goRotateCube, gorotatecube => goRotateCube.transform.localPosition.x);
Debug.Log("监听到goRotateCube.transform.localPosition 位置改变");
goRotateCube.gameObject.transform.localScale = new Vector3(2, 2, 2);
}
/// <summary>
/// 可以等待一个协程
/// </summary>
/// <returns></returns>
private async UniTask FooCoroutineEnumerator()
{
await SayHello100Times();
Debug.Log("100次hello man说完啦!");
}
/// <summary>
/// 说100次你好
/// </summary>
/// <returns></returns>
private IEnumerator SayHello100Times()
{
yield return new WaitForSeconds(2);
for (int i = 0; i < 100; i++)
{
Debug.Log("hello man");
}
}
//可以等待一个task run
private async void TaskRunTest()
{
int resule = await Task.Run(GetRandomNumber);
}
/// <summary>
/// 获取一个随机数
/// </summary>
/// <returns></returns>
private int GetRandomNumber()
{
int ran = UnityEngine.Random.Range(0, 100990);
return ran;
}
}
RotateCube 的代码,挂载于方块上,
using UnityEngine;
public class RotateCube : MonoBehaviour
{
void Update()
{
// 绕Y轴旋转
transform.Rotate(Vector3.up, 50 * Time.deltaTime);
}
}