ちゃんと UniTaskのReadmeに書いてありましたね。
https://github.com/Cysharp/UniTask
await UniTask.WaitForEndOfFrame()
is not equilavelnt to coroutine’syield return new WaitForEndOfFrame()
. Coroutine’s WaitForEndOfFrame seems to run after the PlayerLoop is done. Some methods that require coroutine’s end of frame(ScreenCapture.CaptureScreenshotAsTexture
,CommandBuffer
, etc) does not work correctly when replace to async/await. In that case, use a coroutine.
コルーチンの yield return new WaitForEndOfFrame()
は PlayerLoopが終わってから実行されるようで、ScreenCapture.CaptureScreenshotAsTexture
のような完全にフレームが終了するのを待つ必要があるメソッドではそちらを使うべきとのことです。
クラッシュしたコード
using Cysharp.Threading.Tasks;
using UnityEngine;
public class CaptureScreen
{
private Texture2D _texture;
public async UniTask CaptureWholeScreenAsync()
{
await UniTask.WaitForEndOfFrame();
_texture = ScreenCapture.CaptureScreenshotAsTexture();
var bytes = _texture.EncodeToJPG();
}
}
修正したコード
using System.Collections;
using Cysharp.Threading.Tasks;
using UniRx;
using UnityEngine;
public class CaptureScreen
{
private Texture2D _texture;
public async UniTask CaptureWholeScreenAsync()
{
await RecordFrame().ToObservable();
var bytes = _texture.EncodeToJPG();
}
private IEnumerator RecordFrame()
{
yield return new WaitForEndOfFrame();
_texture = ScreenCapture.CaptureScreenshotAsTexture();
}
}
備考
Unity 2020.2の Release Note に ScreenCapture.CaptureScreenshotAsTexture
でクラッシュするバグを直したよ〜という記述があるので、古いバージョンでは UniTaskとか関係なくクラッシュするのかもしれないです。
sassembla/EditorScreenshotScript – GitHub Gist
What’s new in Unity 2020.2.0 – Unity