首先
我们将在名为 Studio Shimazu 的 Unity 在线社区举行学习会议。
该文件将是 UniTask 的简要总结。
目录
- 关于同步
- 关于异步处理
- 协程审查
- 关于等待/异步
- 关于线程
- UniTask 的不幸之处
- 结论
关于同步
执行多个进程时,进程按顺序一一执行
using UnityEngine;
// ======================================================================
// 同期処理について
// ======================================================================
public class Sample01 : MonoBehaviour
{
void Start()
{
A();
}
void A()
{
Debug.Log("A");
B();
Debug.Log("C");
}
void B()
{
Debug.Log("B");
}
}
执行结果为 A → B → C
图示时是这样的
关于异步处理
执行多个进程时,进程在执行结果之前返回
using System.Collections;
using UnityEngine;
// ======================================================================
// 非同期処理
// ======================================================================
public class Sample02 : MonoBehaviour
{
void Start()
{
A();
}
void A()
{
Debug.Log("A");
StartCoroutine(B());
Debug.Log("C");
}
IEnumerator B()
{
yield return new WaitForSeconds(1);
Debug.Log("B");
}
}
执行结果为 A → C → B
图示时是这样的
协程审查
using System.Collections;
using UnityEngine;
// ======================================================================
// コルーチンの復習
// ======================================================================
public class Sample03 : MonoBehaviour
{
void Start()
{
StartCoroutine(SampleCoroutine());
}
IEnumerator SampleCoroutine()
{
Debug.Log("スタート");
// 2秒待機する
yield return new WaitForSeconds(2f);
Debug.Log("ゴール");
}
}
有了这种感觉,2秒后就可以像〇〇那样处理了。
协程也有缺点,
- 函数不能有返回值(严格来说可以)
- 除非继承了 MonoBehaviour,否则无法使用
- 当游戏对象被销毁或隐藏时处理停止
等等。
关于等待/异步
await/acync 是 C# 中的异步处理函数。
不像协程,它可以有一个返回值,
它可以在没有 MonoBehaviour 的情况下使用。
但是,由于即使游戏对象被破坏它也会移动,
你应该小心。 (稍后会解释。)
using UnityEngine;
using Cysharp.Threading.Tasks;
using System;
// ======================================================================
// お試しUniTask
// ======================================================================
public class Sample04
{
async void Start()
{
await Test();
}
async UniTask Test()
{
Debug.Log("スタート");
// 2秒待機する
await UniTask.Delay(TimeSpan.FromSeconds(2));
Debug.Log("ゴール");
}
}
用 await/async 替换协程如下所示:
using UnityEngine;
// ======================================================================
// お試しUniTaskその2
// ======================================================================
public class Sample05 : MonoBehaviour
{
async void Start()
{
Sample05_2 sample05_2 = new Sample05_2();
// Test()がreturnするまで待機する
var str = await sample05_2.Test();
Debug.Log(str);
}
}
using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
public class Sample05_2
{
public async UniTask<string> Test()
{
Debug.Log("スタート");
// 2秒待機する
await UniTask.Delay(TimeSpan.FromSeconds(2));
return "ゴール";
}
}
这就是返回值的样子。
顺便一提,
var str = await sample05_2.Test();
await 表示等待直到进程完成。
如果不写这个await,“str”会输出为空。
关于线程
线程意味着在运行程序时
让它作为多线程处理,
它可以作为单线程处理。
以游戏制作为例,
在游戏中进行计算的过程和
我认为有一个为游戏绘制图形的过程。
如果您通常使用 Unity 进行生产,则使用单线程
由于这两个进程同时运行,
如果计算过程变得复杂,它就会变得繁重。
因此,让我们让另一个线程来做计算部分!
你可以像这样使用它
详细的我就不写了,不过C#本来就有一个线程处理函数叫Task。
它在 Unity 中是一个难以使用的功能,但 UniTask 使它易于使用。
变得。
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
// ======================================================================
// お試しスレッド処理
// ======================================================================
public class Sample06 : MonoBehaviour
{
async void Start()
{
Debug.Log(Thread.CurrentThread.ManagedThreadId);
// 処理するスレッドの変更
await UniTask.SwitchToThreadPool();
Debug.Log(Thread.CurrentThread.ManagedThreadId);
// 処理するスレッドをメインスレッドに変更
await UniTask.SwitchToMainThread();
Debug.Log(Thread.CurrentThread.ManagedThreadId);
}
}
这很容易,但这是切换处理线程。
实际上,如果它不是主线程,Unity的标准变换等。
不能用,不过这次就简单介绍一下。
UniTask 的麻烦部分
最后总结一下UniTask比较麻烦的地方。
以至于我想知道是否可以因此使用协程进行个人开发。
如上所述,即使 GameObject 被销毁,UniTask 进程也会继续进行。
因此,如果要在销毁时停止处理,则必须自己编写该处理。
这一次,如果您左键单击,则销毁您自己的游戏对象并执行该过程。
编写代码停止
using UnityEngine;
using Cysharp.Threading.Tasks; // UniTaskに必要
using System.Threading; // CancelToken系に必要
using System;
// ======================================================================
// お試し中断処理
// ======================================================================
public class Sample07 : MonoBehaviour
{
private CancellationTokenSource _cts = new CancellationTokenSource();
async void Start()
{
Debug.Log("Start");
// トークンソースからトークンを生成
CancellationToken token = _cts.Token;
// 非同期が止まったときの例外を書かないとエラーになる
try
{
await A(token);
}
catch (OperationCanceledException)
{
Debug.Log("処理を強制的に終わらせたよ");
}
}
// 5秒待機するUniTask
async UniTask A(CancellationToken token)
{
await UniTask.Delay(5000, false, PlayerLoopTiming.Update, token);
Debug.Log("待てたよ");
}
void Update()
{
// クリックしたらキャンセル
if (Input.GetMouseButtonDown(0))
{
Destroy(gameObject);
}
}
// gameobject破壊時にメモリの開放
void OnDestroy()
{
_cts.Cancel();
_cts.Dispose();
}
}
我对它不是很熟悉,但是我通常不会使用 Dispose() 来释放内存,
你必须编写个人开发中不经常使用的流程,例如try-catch语句中的异常处理。
相反,如果你想研究这样的 C# 函数,最好在 UniTask 上工作。
是不是。
综上所述
我整理了一份学习材料清单。
如果有任何错误,我很抱歉。
如果你能到时候告诉我会很有帮助!
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308632068.html