Тёмный

Best practices: Async vs. coroutines - Unite Copenhagen 

Unity
Подписаться 1,2 млн
Просмотров 70 тыс.
50% 1

Before async was introduced in Unity 2017, asynchronous routines were implemented using coroutines and/or callbacks. This video covers the benefits of async over coroutines. You'll see how one example problem - building an asynchronous prompt popup - can be solved using async vs coroutines.
Speaker:
Johannes Ahvenniemi - Seriously Digital Entertainment
Slides available here: www.slideshare.net/unity3d/be...

Игры

Опубликовано:

 

27 июл 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 61   
@manituan4956
@manituan4956 4 года назад
It's common practice to rename async methods by adding the suffix "Async". Utils.LoadScene -> Utils.LoadSceneAsync Good talk!
@jeangodecoster
@jeangodecoster 4 года назад
My #1 point for using Async is that you can use it inside scriptable objects and standard C# classes
@chromezephyr8959
@chromezephyr8959 9 месяцев назад
This. Scriptables that have functionalities inside must use async.
@masonwheeler6536
@masonwheeler6536 4 года назад
27:16: "Finally, coroutines are familiar to most Unity developers. Async isn't." Counterpoint: Async is familiar to most C# developers starting out with Unity, but show them coroutines and they're like "what in the world is this crap?!? Why not just use async?"
@joncross5166
@joncross5166 3 года назад
This was me a few days ago!
@normalhumanbeing6066
@normalhumanbeing6066 3 года назад
this is exactly what i was thinking!!!
@peteruelimaa4973
@peteruelimaa4973 3 года назад
Jep!
@restushlogic5794
@restushlogic5794 3 года назад
Lol me.
@__dane__
@__dane__ 2 года назад
There’s definitely more documentation/tutorials/information out there about coroutines for Unity then there is for using async with Unity
@mandisaw
@mandisaw 4 года назад
Coming from a Java background, multithreading/asynchronous coding in C#/Unity has been one of the biggest challenges to wrap my head around. I've gotten really used to Futures, with custom-configured ExecutorServices to handle thread management and UI syncing/callbacks. But async/await (and its kissing-cousin, Promises) definitely provide an easier mental transition - if you can keep straight what can happen in a worker/non-main context and don't mind relinquishing control over where/how your code will ultimately run*. I still feel hobbled, but at least I can move around a little bit faster :) * There was a GDC '17 AI summit talk with a technical deep-dive into managing core-usage while using asynchronous code that folks should check out - Beyond Framerate: Taming Your Timeslice Through Asynchrony
@Flem100DK
@Flem100DK 2 года назад
I think he was super good, I could actually follow! Thx for this mr. Suomi! :)
@sokrates297
@sokrates297 4 года назад
Perfect timing, thank you!
@slowdragon4169
@slowdragon4169 4 года назад
whenever im having trouble sleeping i jsut turn up this talk. its so damn good
@imaginationrabbit
@imaginationrabbit 4 года назад
Great presentation- thank you.
@irpgTV
@irpgTV 4 года назад
Bad thing is WebGL still not support for async right now. I have trying to use async to load Addressable Asset but editor shows that it doesn't support right now...
@IbakonFerba
@IbakonFerba 4 года назад
Using this for UI solves so many problems!
@harrysanders818
@harrysanders818 4 года назад
Enjoyable Talk! Clear explanations. Thanks very much
@tihomirgvero8454
@tihomirgvero8454 4 года назад
Is there any official Unity documentation about Async?
@FranciscoTChavez
@FranciscoTChavez 4 года назад
When async was put into Unity, I didn't have much use for it because I already knew more than one way to create a background thread. For me, the big issue with background threads is that I don't always know what will and won't run from a background thread in Unity. For instance, the error logging that he mentioned in the "Exception Hiding" Section of his talk; that's one of the things that doesn't work in background threads. Unity has a lot of things that doesn't work in background threads; it's an issue I've come across quite a bit when coding in Unity. Even calling the ToString() method on an Exception from an background thread will give you a warning because that can throw an Exception on certain Unity API items when called from a background thread. One of the hopes I have for DOTS, is that it might enable things that didn't work background threads (before now) to run in background threads in the near future. Coroutines run on the main thread, therefore, they have greater access to the Unity API. You can run things in a coroutine that can't run in async because the coroutine runs on the main thread. For instance, if you are doing a lot of interactions with the Graphics class or running Compute Shaders, you will be stuck in the main thread. I'm not trying to say that async is bad. It's a nice, short, and quick way to create a piece of code that runs in a background thread that returns a result without blocking the parent thread (which may or may not be the main thread). While coroutines are great for breaking up a long running (or multi-state) process that can't leave the main thread. Shoot, I've even launched plenty of non-blocking, background threads from coroutines, just so that I can offload work from the main thread while maintaining current state in long running processes. Both items have their uses.
@r1pfake521
@r1pfake521 4 года назад
I think you miss some information about about the way async works, first of all async uses tasks, not threads. Yes most tasks will run on background threads, but not all (just google tasks vs threads if you want to know more details about the difference). Next the tasks don't have to run on a background thread, the async "callbacks" use the SynchronizationContext. The "default" SynchronizationContext will (in most cases) run the async tasks on a background thread. But like you said a background thread can't access the Unity API, that's why Unity has a custom SynchronizationContext which synchronizes all async "callbacks" back to the main thread. So you can access the Unity API with async mehods. If you want to use async methods which run on the background and don't have to access the Unity API you can still do this by calling ConfigureAwait(false) then the SynchronizationContext will be "ignored" and the async "callback" will (in most cases) run on a background thread.
@whoisj
@whoisj 4 года назад
@@r1pfake521 Um.. . I hate to be the first to tell you this but tasks are just promise objects for interacting with work executed on other threads. They don't really exist, except as a logical model for understanding threading.
@GladerDev
@GladerDev 4 года назад
@@whoisj After reading both people's comments I have to say that your comment is very unhelpful. R1PFake's reply to Chavez about how async/await in .NET/C# is not implictly multithreading your code, and describing the purpose and meaning of the synchronization context which does control continuations, is a very appropriate answer to Chavez complaint.
@phobos2077_
@phobos2077_ 4 года назад
@@r1pfake521 Not to mention you can actually write Async methods that work via Unity's coroutines (via custom Awaiters returned from extension methods on, for example, YieldInstruction) - so you not only know your async methods are 100% work on main thread, you can actually control the context they work in (which is important for games with complex updates like ECS-based architectures with interdependent systems etc.)
@augustopinheiro
@augustopinheiro 4 года назад
I'm pretty confused about the popup example, why does he load a whole scene just for the popup? And why would he need to select the buttons? Sorry, I'm just pretty confused...
@Tech_Alchemy
@Tech_Alchemy 4 года назад
If you play the game he refers to it makes sense then.
@jonathansaindon788
@jonathansaindon788 4 года назад
It's easier to manage the UI lifetime by loading and unloading a scene (additive or not) than instantiating UI gameobjects directly, keeping references to them somewhere and destroying them at the end. It find it particularly usefull when switching between non-additive UI scenes. Like going from the multiplayer server list UI to the game loading UI for example. The server list UI only needs to know that when you click the Join button it loads the GameLoading scene non-additively so that ServerList UI gets destroyed.
@mandisaw
@mandisaw 4 года назад
I can imagine they might keep all their dialogs in a dedicated scene, with all accompanying logic, and then just call up that scene from anywhere with dialog parameters set as appropriate.
@tuseroni6085
@tuseroni6085 Год назад
i had recently needed to convert some coroutine logic to async entirely because i couldn't make it await a result. so in my case i had a message that would move across the screen using ui builder and transitions. i didn't want the next action to happen until the message for the current action had shown and gone (so for example i have a "program" called "Hellhound" in the game and it attacks my player "DEADFEED" it first has to spot him, if it does a message shows saying "Hellhound spotted DEADFEED" the hellhound then need to wait for that message to finish before moving on to its next action of attacking DEADFEED, and it should wait til that message is gone before showing the message for "HIT" or "MISS" and when that is done then it applies the damage and shows a message for that. the code also simulates a dice roll, but an option is available to get a dice roll from the user, a diceware option, so in that case when the hellhound looks for DEADFEED then a prompt would need to show up asking the player to roll 1D10 and put in the number, the REF would also be asked, if the game is being played in online mode, to roll 1D10 so my enemies (programs) have logic that depends on the result of 1 or many asynchronous inputs or which has to wait for certain actions to continue. async made this much, much simpler, i had to make sure all my functions were async and returned a task, in the case of void, or task in the case of one that returns and i had to move the state machine out of a coroutine and into an async so it could await these results, but it's worked pretty nicely.
@AndreaLeganza
@AndreaLeganza 3 года назад
Every time i see on Unity docs and their videos the use of "public" i get chills...
@OddStare
@OddStare 4 года назад
Good god almost fell asleep in the train back home good thing there is only two concepts to explain
@sunnycareboo8924
@sunnycareboo8924 3 года назад
Why not both? Unitask exists...
@chromezephyr8959
@chromezephyr8959 9 месяцев назад
Just stick to Async.
@MohammadFaizanKhanJ
@MohammadFaizanKhanJ 2 года назад
My first experience with async .obj file loading, it is very very slow!
@gecko6872
@gecko6872 Год назад
Super informative, but specifically for Unity and specifically for this use-case, why would using async/await as demonstrated be more efficient than instantiating a popup prefab, instantiating the desired number of buttons (using layout elements), and doing Button[i].OnClick().AddListener( () => some function(arguments) ) It seems to me that, for pop-up boxes, it is more efficient and allows greater flexibility to assign the desired Actions directly to the buttons...
@tuseroni6085
@tuseroni6085 Год назад
consider the following: if(!await GameController.RollToHit(target, this)) { GameController.EndTurn(this); return 0; } (from gameController) public async Task RollToHit(NetActor target,NetActor Attacker) { ret=false; int D10= await MenuController.ShowMessageBox("Please Roll a D10"); if((ProgramDefense + d10 + InterfaceTotal + Int) > target.defense) { ret=true; } return ret; } (inside MenuController a visualElement using uiElements) public async Int ShowMessageBox(string Message) { while (MessageBoxOpen) { await Task.Delay(250); } var newMessage = Message; MessageLabel.text = newMessage; MessageBoxOpen= true; MessageLabel.AddToClassList("Shown"); while(MessageBoxOpen) { await Task.Delay(250); } return MessageBoxNum.Value; } i'm glossing over a few things and kinda refitting some code i have written here to demonstrate the biggest benefit here is that the code continues right after the input, and the ui is kept pretty separate from the main code (so the menucontroller handles the popup, and likely other ui elements, it handles the click on the ok and cancel to set that field "MessageBoxOpen" to false to allow the async call there to continue. this could also be getting its results from a socket to another program, doesn't matter to the calling program, it just waits to get a result back from...wherever...however the program wants to do it.)
@gecko6872
@gecko6872 Год назад
​@@tuseroni6085 Came back to say that your comment started me down the async road a few months ago, and I cannot imagine coding pop-up items without it anymore. Thank you!
@FredrikHAndersson
@FredrikHAndersson 11 месяцев назад
​@@tuseroni6085 Is there a name to this pattern? Inhouse, I have made a very successful UI framework fully based on async like the speaker here hints at. It is incredible what the pattern has done for stability, cleanliness of code and iteration speed. So much that it ought to have a name and some recognition.
@FredrikHAndersson
@FredrikHAndersson 11 месяцев назад
@@gecko6872 I had a similar journey, but from being at this speech live :D
@snaecooceans8744
@snaecooceans8744 4 года назад
MORE DOTS
@pearz420
@pearz420 4 года назад
ok stop dots
@whoisj
@whoisj 4 года назад
.............. Sorry, had to.
@snaecooceans8744
@snaecooceans8744 4 года назад
@@whoisj Funny .. I'm still waiting for a polish product ..
@user-gl1ls1jx3h
@user-gl1ls1jx3h 4 года назад
KAAAY, DPS, SLOWLY
@MalrickEQ2
@MalrickEQ2 2 года назад
@@user-gl1ls1jx3h And when I say slowly...I mean -
@nathanieldoldersum6169
@nathanieldoldersum6169 4 года назад
At 26:17 How do we fix it? (async throwing null reference). Why not just for the async write: `while (transform)` and it would stop if transform gets null and zero complexity added...
@tryfinally
@tryfinally 4 года назад
*while(this.transform)* will throw because the *this* reference will be null (or null-like) and the transform getter will throw, but indeed you can use *while(this)* and *if(this)* after awaiting to avoid this issue.
@nathanieldoldersum6169
@nathanieldoldersum6169 4 года назад
​@@tryfinally Yep true...
@AnkitSingh-wq2rk
@AnkitSingh-wq2rk 3 года назад
and here i am using async methods in coroutine bruh ...
@warcinm3210
@warcinm3210 2 года назад
you used the Drake meme wrong, mate.
@leejim584
@leejim584 3 года назад
This guy dose have some funny lines for audience but the problem is the way he delivers it...
@PavelFadrhonc
@PavelFadrhonc 3 года назад
I, for one, quite enjoined his dry and somewhat awkward delivery. Suits his character it seems.
@cathrynm
@cathrynm 2 года назад
I still hate 'var' -- var is like a cancer.
@MalrickEQ2
@MalrickEQ2 2 года назад
Me too, I dunno why people like it. Our team doesn't allow it.
@Valentyn90A
@Valentyn90A 3 года назад
Nice memory leak in that PressButton async example *facepalm*
@nenicenerd
@nenicenerd 4 года назад
как. же. он. медленно. говорит. делая. такие. долгие. паузы. что. даже. на 1.75 скорости. его. не возможно. слушать.
@JackFastGame
@JackFastGame 2 года назад
Может это не его родной язык, поэтому ему тяжело?
@Boolai
@Boolai 4 года назад
Jeeze. Can we get a little less boring. At least Mike makes it entertaining.
@sicksharkx92
@sicksharkx92 4 года назад
PLEase GOD Change speaker........
Далее
Unite Austin 2017 - S.O.L.I.D. Unity
1:07:18
Просмотров 83 тыс.
Maybe a little TOO much gel 😂
00:12
Просмотров 10 млн
ЭТОТ ПЕНЁК ИЗ PLANTS VS ZOMBIES - ИМБА!
00:48
5 Fatal Coroutine Mistakes Nobody Tells You About
18:15
Truth about Singletons in Unity | New GameDevs WATCH!
16:49
2DROTS vs RISENHAHA! КУБОК ФИФЕРОВ 2 ТУР
11:31