I don’t believe there’s any guarantee that your method would get to continue on the next Unity frame; theoretically, multiple frames could elapse before it gets a chance to check. (Once you call Task.Yield(), the system gets to decide how to prioritize your function relative to other stuff it’s trying to do, and there’s no guarantee it will get back to you promptly.)
Also, a lot of UnityEngine is not threadsafe. I’m not sure whether it’s OK to call Transform.Translate or access Time.frameCount from an async method. (I’m not sure it isn’t safe, but I’m not sure it is, either.) It might even appear to work in some test cases but then give weird errors in others.
If you want to do something every frame, it’s probably smarter to put it in Update.
If your performance requirements really require you to update transforms in tasks (like a there’s 10000x10000 armies clash in one scene) i suggest you to look into ecs+jobs.
Yes. Just remember that Coroutines run on the main Unity-Thread, and tasks don’t.
So you can start running into issues when you try to use ‘Unity-Things’ inside your task.
That can be as quick as using a ‘.gameObject’ or a ‘GetComponent’ (or even Debug.Log in some instances)
Even synchronous jobs can be very useful! I use Bursted Jobs to do expensive AI calculations for a game, using a gradient descent algorithm. It was a huge speedup.
…I really should make those async, because the AI can afford to make one-frame-out-of-date decisions, can’t it?
Yes. Running your jobs whilst the engine is doing rendering of the frame allows you to dump a bunch of work in a timeframe that’s normally somewhat ‘unused’ .
I’d do the management of that job in LateUpdate.
Yeah I had to learn it a few years ago (back when none of it was documented, or even stable) in order to position & render a bunch of Stars (based on real-world data).
Went from +/- 400 GameObjects struggling to update once per second (split out over different frames) to 10k+ stars recalculating their position from scratch (Basically a bunch of trigonometry) once every 4 frames at <2ms total per frame
Sh*t’s crazy when you see performance-gains like that.
Unity 2023 introduced a new Awaitable.NextFrameAsync API that can wait for the next frame. Haven’t tried it myself, but Tarodev recently released a great video on this topic.
Use UniTask package. They have everything needed like await UniTask.NextFrame() and it is totally okay to use it exclusively in your async code instead of standard Task because UniTask was designed for no-garbage.