Taming Coroutines - Unity Tips
Вставка
- Опубліковано 27 чер 2024
- In this video, I show an interesting idea of how to improve the way we start coroutines in Unity. This approach allows us to easily check whether or not our coroutine is still running or even dispatch an event once it's finished. Similarly to how AsyncOperations work.
Sources:
gist.github.com/aarthificial/...
Support me on Patreon:
/ aarthificial
Timestamps:
0:00 IEnumerator
1:58 Controlling a coroutine
2:53 Waiting for other coroutines
#unity #unitytips #gamedev
First of all great Video, i am a big fan of your stuff, i just want to add something regarding yielding other Coroutines.
From my experience, yielding for a Coroutine can lead to problems in some cases. If you stop the Couroutine, you are waiting for, with StopCoroutine() or StopAllCoroutines() the yield will not count that as the Coroutine finishing correctly. The Code after the yield will never be executed and the Coroutine will be cleared at some point by the garbage collector. This is only a problem, if your Coroutines run on 2 seperate GameObjects, or you have some case where only one Coroutine is killed, however its definitelly something you should be aware of.
I hope that can help someone ^^
Thanks! Didn't know it was the case but I just checked and you're right. It almost feels like a bug.
Though, usually, when I'm planning on stopping a coroutine I use something similar to a CancellationToken.
The string-based approach scares me D:
@@aarthificial I completely agree, when i first encountered it i thought it was a bug too, good thing that this case almost never happens :D
@@aarthificial not even surprised any more that unity would do such a thing. Seriously, there are so many weird and unnecessary "almost-bugs" in unity.
That's great additional insight!
@@aarthificial You do not have to use strings to stop a coroutine; StartCoroutine returns a Coroutine object which can be passed to StopCoroutine to stop a specific coroutine.
I don't even use Unity, but your videos are always interesting and well-made that I just have to watch.
Could not have said this better
I started learning Unity a week ago, so I've started revisiting these videos. I used to watch them just for fun, but now they have so much more relevance for me.
These clean and minimalistic visuals are excellent. Quite satisfying to watch. Great video :)
This video is incredible!! Its super helpful and the animation and educational quality is off the charts
After seeing Brackeys use Coroutines with this odd IEnumerator syntax a couple of times, I was always mystified by how it worked; this video made everything click into place and gave me a nice 'aha!' moment. Well done!
Half of this melts my brain. This guy is on another level of intellect.
Keep in mind that this 5 minute video probably required much more than 5 minutes of preparation, not to mention months to years of experience in Unity dealing with coroutines and thinking/refining how to best approach them.
ACtually one of the smartest game devs i have ever seen. Every video is short, to the point well edited and explained and genuinely if all these fake youtuber trying to get views devs were like him then the world would be a better place
This is a very short but amazing explanation of how coroutines work in Unity but also how IEnumerable functions work in C#. Brilliant video!
Heads up: The names "IEnumerator" and "IEnumerable" threw me off for a bit - I kept conflating them and it led to a lot of confusion.
C# interface names aside, this video is fantastic! Thanks for putting it together :)
Still feels good to be early.
that outro though - "possibilities are endless, unlike this video"
It seems like a quote, so imma make it one
basically everything went over my head but great video
This is literally the only video I could find with an intuitive explanation of coroutines.
Unity doesn't even have a video period
Awesome video, I instantly cleaned up some weird coroutine madness I had setup afterwards
This is just the right video I needed this month. Thank you!!!
Very great video! I had no idea you could pause IEnumerators like that. Thank you!
Your video's always motivate me to continue on my projects :)
It's great to hear that!
Amazing video! You really can simply explain complicated things. I knew about how Coroutines work intuitively (because of the type that it returns), but never dived into this deeply.
I had a lot of success using UniTask for asynchronous code because the native coroutines are very limited and require a lot of boilerplate to do more complex things. To make generators possible it contains a "Channel" abstraction which essentially behaves like an async iterator for async foreach and the generator just calls a write message instead of yielding.
But the library doesn't stop you from using native coroutines for anything you need and even provides adaptors for C# Tasks as well as coroutines. Its first focus is on performance so the library overhead is surprisingly small.
The library brings the default async facilities of C# to unity and nicely integrates it into the single-threaded game loop but also allows dispatch of long-running tasks to a background thread pool exactly as .net does. It can decouple a lot of complex logic from the polling nature of the unity update method but also allows frame by frame logic with await UniTask.Yield() which just waits for the next frame like yield null.
I am not affiliated with the library in any way btw.
really interesting stuff!
Wow, this is a great video! Explaining in simple terms how these complicated things work and even showing how they can be improved. Great work as always!
Fantastic video dude, explained so clearly and edited to perfection. Smashed it!
love the design and quality of your videos, also the information in them, keep it up
Excellent video, super clear explanation.
Can't wait to see the next video!!
You just blew my mind with the tidbit that you can yield a coroutine with another coroutine… and now the rat’s nest of coroutines grows larger 😅
Best explanation I have seen so far. Other videos just tell u to write yeild return and don't tell u what it means. Great video!
never change please, these both satisfying to watch and Informative, even if you have years of experience with C# and Unity
First time I actually understood coros
It's a great and concise tutorial. Thank you. And nice touch with isDone property.
Great video yet again!
"The possibilities are endless. Unlike this video." *video immediately ends*
Thanks for making this veideo!!!
Great vid
Pretty cool vid!
It looks like a recipe for debug nightmares, but perhaps that is true of all parallel constructs.
Fortunately, coroutines are run concurrently on the main thread, there's no parallelism involved. Which makes things a bit easier to reason about
Oh, so that's why coroutines in Unity return IEnumerator.
based new upload
not a single word in this video made sense this is why i know i could never learn to code................... good job on being math and doing smart
Try reading the documentation on specific things if you don’t understand what they mean. A large chunk of the time you spend coding actually consists of looking up what something means or how to do something.
I'm sorry, but that's a really silly conclusion you've got there. If you are yet to learn how to code, it's perfectly normal to not understand things - that's where the "learn" part comes into play.
Also, this video is nowhere near being an entry-level tutorial. It's targeted more towards people who already know Unity and a thing or two about coroutines. So don't let it bum you out!
@@aarthificial i meant this more in a joking way than being seriously negative towards myself - however i will say that coding and game development has always interested me, but any time i try to pick it up i immediately run up against a barrier. as soon as the python class starts talking about booleans or the godot tutorial tries to explain branches my brain just melts. i'm not upset, i'm just genuinely amazed that people like aarthificial can understand such a complex concept so well. my brain just isn't wired for math and logic :/
I don't get what this is all about but i still watched it and i don't know why other than this is a great channel.
Great videos! Congrats
Can I you share with us which kind of tools that you use to make those videos?
These code snippets and all the visuals that you put on are excellent to share knowledge
Thanks!
I'm using After Effects and Illustrator for all my visuals
nice ;D
Mmm... right right, very interesting stuff. Now, can you explain what that "see hash" thing is?
Now for real, I will need to come back to this video in a couple of years.
Watching this video is like:
- yeah, cool! I know all this, what an iterator is, kind of cool how he explains it though.
video reaches 3:36
- ok, now this escalated quickly!
aarthificial, thanks for all the great content you bring to us! :)
Could I know which theme are you using for your text editor? :D
It's "Dracula" for Rider
@@aarthificial alright! Thank you so much! 💜
@@aarthificial hello again! The Dracula theme I've found has the main colour pink instead of orange, did you customize it or I've not found the correct one?
It's a bit confusing because Dracula is the default dark theme for any IntelliJ-based IDE (the orange one) but there's also a plugin called exactly the same (the pink one).
But depending on your IDE, you should be able to find the default one. Here's one for VS Code for instance:
marketplace.visualstudio.com/items?itemName=trinm1709.dracula-theme-from-intellij
@@aarthificial Aaah, I thought I answered you, sorry! Thank you so much for the link! I've installed it and I like it a lot. I might change to Rider rather soon. Thanks again!
I would love to know how you do your animations, they are just so helpful!
I make them using After Effects and Illustrator
By the way, what program do you use to make these beautiful animations? They look real nice
Thanks! It's the good ol' After Effects
@@aarthificial Alright thanks. Guess I'll have to go learn some After Effects then hahah
Ive always found Unity's coroutines to be kind of weird. Im using a library called UniTask (both in production code and personal projects) which feels much more clean and professional. Unlike C#'s async/await logic it used Unity's game loop which means it can also work in WebGL builds.
This is really interesting to compare with Python's coroutines (asyncio.gather) and JavaScript's Promises (Promise.all). I've never heard of a use case where we just wait for any coroutine to finish and then we close out the generator. Could you give an example of where waiting for any one coroutine to finish and then stopping would be useful?
I can't think of a situation where it would be useful. I didn't include any code after that check as to keep things simple but I'm assuming that there would be some additional logic afterward.
For example, I use this when loading saves to postpone the loading indicator. So that it only shows up if the loading has been taking more than 200ms
As a side note: C# has its own async/await syntax really similar to the one in JavaScript and they have things like Task.WhenAny() etc. I'm guessing that Unity went for a generator/iterator based solution because it gives them more control over how stuff is invoked. Kinda like redux-saga in JavaScript.
@@aarthificial Cool! The delayed loading indicators is a really good idea which I would have never considered; it helps to maintain a feeling of seamlessness on faster machines.
I'd like to see and example of actual game code which uses this technique. Without a concrete example, it's a bit hard to see real potential in this
what do you use to animate your videos?
I want to make a poster of this video
someone else said your videos motivate them to finish their projects, tbh for me they do the opposite just because of how little I understand stuff because of how little programming knowledge I have lmao (not your fault ofc, im just dumb)
Not understanding something because of the lack of knowledge does not make you dumb!
I oftentimes assume that the viewer will already know certain things simply because it makes the video shorter (I need to keep them short bc I don't have a lot of time to make them)
But there's definitely a lot of content out there - doing a much better job at explaining things from the ground up - that you may find inspiring!
Great video but.... async/await tho bruh (with UniTask)
await UniTask.WhenAll(UniTask.Delay(1000), UniTask.Delay(2000));
I'm a webdev by profession so async/await is my jam obviously.
But my experience with it in Unity was really poor. Mainly, cancelling tasks when disabling an object / unloading a scene etc.
Although I was using a different library so I may give this one a shot.
@@aarthificial Fair, although CancelationTokens kinda got you covered. Anything else around object destruction kinda feels like something you'll need to or already are managing anyway.
I saw in an earlier via that you're useing addressables. I am too, and I really hated managing async/wait code with callback so just wanted to point it all out. Seems like you got it tho 😉
UniTask is nice since it manages the Synchronization Context for you so task based operations defualt to the main thread. Which I think Unity devs want most of the time
Hey@@aarthificial , Thank you for your amazing content. but in this case unfortunately I think you teaching more people to use Coroutines while UniTask is so much(much much) batter. I have moved into my current job where all of the code is written by Unitask and Unirx, and it is just amazing compares to previous jobs I had. I think you should play with Unitask and Unirx and make a new video apologizing for this video😬
IEnumerator?
More like I dont know what any of that means dude...