Merge pull request #496 from Cysharp/hadashiA/awaitable
Add EndOfFrame implementation using `UnityEngine.Awaitable`master
commit
acc71550c9
|
@ -84,8 +84,13 @@ async UniTask<string> DemoAsync()
|
|||
await UniTask.Yield();
|
||||
await UniTask.NextFrame();
|
||||
|
||||
// replacement of WaitForEndOfFrame(requires MonoBehaviour(CoroutineRunner))
|
||||
// replacement of WaitForEndOfFrame
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
await UniTask.WaitForEndOfFrame();
|
||||
#else
|
||||
// requires MonoBehaviour(CoroutineRunner))
|
||||
await UniTask.WaitForEndOfFrame(this); // this is MonoBehaviour
|
||||
#endif
|
||||
|
||||
// replacement of yield return new WaitForFixedUpdate(same as UniTask.Yield(PlayerLoopTiming.FixedUpdate))
|
||||
await UniTask.WaitForFixedUpdate();
|
||||
|
@ -497,6 +502,8 @@ It indicates when to run, you can check [PlayerLoopList.md](https://gist.github.
|
|||
`PlayerLoopTiming.Update` is similar to `yield return null` in a coroutine, but it is called before Update(Update and uGUI events(button.onClick, etc...) are called on `ScriptRunBehaviourUpdate`, yield return null is called on `ScriptRunDelayedDynamicFrameRate`). `PlayerLoopTiming.FixedUpdate` is similar to `WaitForFixedUpdate`.
|
||||
|
||||
> `PlayerLoopTiming.LastPostLateUpdate` is not equivalent to coroutine's `yield return new WaitForEndOfFrame()`. Coroutine's WaitForEndOfFrame seems to run after the PlayerLoop is done. Some methods that require coroutine's end of frame(`Texture2D.ReadPixels`, `ScreenCapture.CaptureScreenshotAsTexture`, `CommandBuffer`, etc) do not work correctly when replaced with async/await. In these cases, pass MonoBehaviour(coroutine runnner) to `UniTask.WaitForEndOfFrame`. For example, `await UniTask.WaitForEndOfFrame(this);` is lightweight allocation free alternative of `yield return new WaitForEndOfFrame()`.
|
||||
>
|
||||
> Note: In Unity 2023.1 or newer, `await UniTask.WaitForEndOfFrame();` no longer requires MonoBehaviour. It uses `UnityEngine.Awaitable.EndOfFrameAsync`.
|
||||
|
||||
`yield return null` and `UniTask.Yield` are similar but different. `yield return null` always returns next frame but `UniTask.Yield` returns next called. That is, call `UniTask.Yield(PlayerLoopTiming.Update)` on `PreUpdate`, it returns same frame. `UniTask.NextFrame()` guarantees return next frame, you can expect this to behave exactly the same as `yield return null`.
|
||||
|
||||
|
|
|
@ -75,6 +75,12 @@ namespace Cysharp.Threading.Tasks
|
|||
return new UniTask(NextFramePromise.Create(timing, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
public static async UniTask WaitForEndOfFrame(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await Awaitable.EndOfFrameAsync(cancellationToken);
|
||||
}
|
||||
#else
|
||||
[Obsolete("Use WaitForEndOfFrame(MonoBehaviour) instead or UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate). Equivalent for coroutine's WaitForEndOfFrame requires MonoBehaviour(runner of Coroutine).")]
|
||||
public static YieldAwaitable WaitForEndOfFrame()
|
||||
{
|
||||
|
@ -86,6 +92,7 @@ namespace Cysharp.Threading.Tasks
|
|||
{
|
||||
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue