Just going to say, completely sincerely, listening to your explanations is a breath of fresh air between being drowned by a LOT of other people's confusing babble. Thank you for your content
Thanks for the video, I didn't really have a good idea of a nice practical way to use coroutines until you mentioned the idea of something that does not need updated every frame as an example.
Huh, coroutines look awfully similar to interrupts, but instead of calling a function like interrupts do, it resumes execution. Thanks for this video, I now understand coroutines. Took me a while to get it!
Excellent video. Making similar ones for any other unity-specific classes & patterns would absolutely be successful for you & useful for the audience. Based on the related videos it looks like you're doing just that, so keep up the great work!
Thank you so much for this video. I'm quite rusty on coding, so I was looking for a quick, concise, and well-delivered refresher. This was exactly what I needed.
Great video, very good description of how they work. My absolute favorite Unity addon is MEC(free version) More Effective Coroutines. I rarely use Unity coroutines.
Another great one! How did I not find your channel earlier??! :D Btw: Lerp functions can (and should) reach their endpoint - but many people use them in another way than they were intended. The intention is do allow a linear interpolation, T, between two values A and B: Lerp(A, B, T). The interpolation value T should be varied over time (from 0 to 1), to give a linear animation from value A to B over a given timeinterval. If the animation needs to be anything other that linear, the T value can be passed through an easing function (example below). The method show on your screen, while it is working to give a smooth animation, it does have the drawback of never reaching its target, since it's only ever moving 10% closer to it's target value each time. And thus you need to correct the position after the loop. Another way to do the animation in the Coroutine, without the post loop correction: IEnumerator FloatDown() { float t = 0.0f; Vector3 start = transform.postition; Vector3 end = startPosition; // the original cached startPosition is where we want to end up. while(t
Thank you for creating this tutorial! Overall the concept and implementation of coroutines are good as shown in the video. But I have a small complain, try make your voice louder in the next video. THank you!
Excellent video, I really wish Unity had more detailed documentation about yield Instructions and what they do for unity...if I'm mistaken I'd welcome someone to correct me but apart from some very basic descriptions of waitforseconds and waitforfixedupdate there isn't much else? So having a video like this to explain them more is really useful.
I've never used a coroutine, but this video sure makes me want to! One way to get a value out of a coroutine could be to pass it a generic class that simply has a bool and a value of the generic as fields. The bool would be whether or not it's done or "returned," the the value is of course the return value. This way, you can store the class as a variable or field and pass it as a parameter to a coroutine in another class. Also about the counter using coroutines, if the coroutine waits for 1 second, then does some stuff, then won't it repeat a little longer than every second? Wouldn't this add up, and if so, how quickly? I would imagine if you're doing simple calculations it would be pretty negligible, but with more complex calculations or over a large timescale, this may add up. A way around this may be to store the value of when the first/previous loop happened and then do some calculation to offset the time to get a more accurate second.
My basic mistake is that, i thought coroutine is just same like update function but coroutine is more precise because it use second, i have no idea that the variable inside coroutine isn't restarting
Dear One Wheel Studio, Someone on Discord told me this is the process to make a player with a slider health bar take damage from a zombie enemy at close range, 4.0 stopping distance away. The zombie has an attack trigger in bolt also, to use an attack animation from Mixamo. Is this the correct process? He Say "Ok, so for your health bar here's the things you need to solve in Bolt." 1. You need a variable to store the player's health. It should be an application variable so it's visible to all flow machines. 2. You need a custom event for the zombie to call. When the zombie attack animation plays => call a custom event "PlayerCheck". Build the custom event for PlayerCheck. In it you want to check the distance between the current zombie and the player. If it's less than 4, decrease the health variable by 20%.
Oh and just for the record. I love the comments. They help with the algorithm for sure. But you’re also welcome to jump on the OWS discord - links in the description
To be honest, the cancelation of Bolt 2 very much took the wind out of my sails in terms of making Bolt video content and frankly almost all things Bolt related. I thought Bolt 2 was the path to making VS a viable tool for small production worthy games. Not AAA games or even III games, but small games made by a team of just a few people or a hobby solo developer. As is, I think Bolt or other VS tools are great at onboarding people to Unity - I can't speak to other game engines. And truthfully, I think that is what Unity sees too. It's a way to get more users and as a result, generate more revenue. And that is more than okay! It's an easier way to get started than C#. It's a gentler way to learn the ins and outs of the game engine. I think it's great for simple prototypes or maybe even a game jam. However, once a project gets beyond the prototype phase I think the shine of VS will wear off. That's what I found personally and with my students - I've used playmaker and Bolt for a total of 5 years in the classroom (I switched to C# this year). Bolt simply doesn't scale well. The lack of classes, functions, events and scriptable objects (all of which Bolt 2 supported) makes it tricky at best to make a complete and polished game. My current project is "simple" and I can not imagine making it with Bolt or other VS tools. Okay, that's a bit long and maybe more than you wanted ;) This topic has been in my head for a while and I even made a rough draft of a video on it... I never published it as I didn't think it would truly help anyone.
@@OneWheelStudio This was a great reply! (not long-winded) I really appreciate the insight. Perhaps Unity's Visual Scripting (formerly Bolt) will eventually have the features Bolt 2 would have.... but it sounds like, regardless, C# is the way to go.
@@OneWheelStudio I really think a video on the state of visual scripting would be amazing, not sure it would be a positive video, but like Shocktor asked, i believe that many of us are in the Bolt limbo, and maybe a nice way of telling us how to fully abandon bolt, or maybe use it only for what it is good for and integrating with C#. Currently I am using bolt for my project and can say it is going fine for some parts, but others i have to use C# to make it work, and frequently try to move the logic to C# or a mix of both, a but messy but it does work, so far...
@@homemacai I've thought about it. Even done a few dry runs. I wasn't convinced it was constructive... I did finally write up a blog post with my thoughts. I'm still not convinced it would be a constructive video. You can read it here. But maybe? onewheelstudio.com/blog/2021/4/29/boltvscsharp
Caching the wait for seconds on start is also a good idea in order to save Garbage collector as far as I know right? oh nvm you already mentioned it n.n
Definitely, yes it is! If you are using it to replace an update function this is particularly helpful as otherwise you'd be creating garbage on a regular basis.
Really informative. I do have a question however. I was browsing Unity forums and saw a handful of people say Coroutines aren't very performant and bad for memory, suggesting they should be avoided. I was wondering if this is true and if so, when is the right places to use them versus coming up with a different solution. Thanks.
I have never had a performance issue with coroutines. If you're trying to make the next esports title then yeah you should worry about everything. If you're just making a game for fun or even a small "commerical indie game" and need something to happen in asynchronous way then use coroutines. I use them fairly generously and there are far bigger bottlenecks in my projects. That said TaroDev has 2 videos on async functions that are pretty great. If you are using Unity 2023 then async functions look to be better than coroutines in just about everyway. With the new features Unity added in 2023 async functions are easy to use and have lost just about all of their downsides. Hope that helps.
Some great advice. Personally, rather than caching a coroutine and doing a null check (which from my understanding is a deceptively expensive operation that dives deep into the C++ side), I simply do a boolean check. When a coroutine starts, set MyCoroutineIsRunning = true and check against that instead.
No I haven't yet. It's on my list, but there are a lot of pitfalls if the use gets remotely sophisticated. Which I suspect is why there aren't a ton of videos on the topic. If I can come up with a reasonable scope for the video I'll make it happen.
Overly long lasting coroutines can affect performance. But when you set for it to pause until a certain condition is true. Does that also affect performance the same way or does pausing it let it exist without performance lost as long as it isn't running.
im trying to create a game (old school jacks game, like knuckles), i need to calculate when the ball hits the ground two times, to turn a method off and replace it with a new method. im not sure where to start, is Coroutines a good place?
Thank you for this video. But can we use a starcoroutine in a class and a method with ienumerator that comes from another class? I try but the results are chaotic.
That's a great question. I'm honestly not sure. I would guess that the garbage collection would clear out the reference once it's no longer in use... but that's just a guess.
I wrote a short test program. Looks like my guess was wrong. The coroutine reference does not return to null. Interesting! public class ReferenceTest : MonoBehaviour { Coroutine coroutine; // Start is called before the first frame update void Start() { coroutine = StartCoroutine(SomeCoroutine()); } // Update is called once per frame void Update() { if (coroutine == null) Debug.Log("Coroutine is null"); else Debug.Log("Coroutine is not null"); } IEnumerator SomeCoroutine() { yield return new WaitForSeconds(2f); } }
Hi! Great video! I had a question regarding the timer. If we wanted to display the timer in the form of min : sec . milliseconds (0: 00.00) would this strategy still be viable/ improve performance? We could achieve this I think by changing countTime to 0.0001f but then wouldn't our coroutine be less efficient as it would run 1000 times every second? Is there a way to use coroutines for this use case or would it be better to just keep something like that in an update function? Thank you!
The idea is to cache the "wait" statements. They cause some garbage collection. So if you are replacing an Update with a coroutine, then it can be good to cache the "wait" rather than create a new instance every time the coroutine runs. This is more important the more often the coroutine runs.
@@OneWheelStudio the use case you demonstrated in the video at timestamp 2:42. I am just wondering if you wanted to output a timer using the minutes: seconds.milliseconds format if you could potentially use a coroutine with something like WaitForSeconds(0.001f) and update time every millisecond? Or is that not the right way of approaching such a problem
I guess it really depends how fast you want the timer to update. I would think if you want it super fast, an update function would be the way to go. The example I showed it as an optimization if you only want it to update every second.
Hmmm. Sounds like maybe autocomplete is not playing nice. That can be a tricky one. But try a search for "Unity autocomplete not working." Sorry wish I could be more helpful than that.
Hey @OneWheelStudio, what are your thoughts on using Coroutines in Unity? I have been working as a Unity Dev for about 2 years now, and it seems companies really don't like using Coroutines for stability, garbage collection, etc. When would you consider an alternative like async or mult-threaded solutions as opposed to Coroutines?
Hmm. Interesting. I've heard other folks mumble about coroutines not being ideal. Truthfully, I don't use them that often in my personal projects. I did when I first got started with Unity - they were everywhere! They're so easy right!?! My personal project mostly makes use of actions/events to trigger things far more so than coroutines. For so many reasons this is my preferred way to wire things ups. I do use DoTween to polish and juice things up - and I think/suspect that is based on coroutines in the background. There definitely can be some garbage collection issues with coroutines - I'm mostly aware of the issue with the wait statements. Which in some cases can be dealt with by caching the wait statement, but I can imagine there could be more. The lifetime of a coroutine is also something that needs to be carefully managed which could lead to some stability issues. I'd be curious to know what other stability issues developers have run into. As for async functions, I have used them, particularly when implementing Facepunch Steamworks. I've done the research to put a video together, but honestly, I was struggling to come up with a general enough use case for a good tutorial. Requesting information from a server (i.e. steamworks) is a great use case for async functions, but for my channel's viewers, I was struggling for something more general. My impression is they are very powerful, not too hard to use at a basic level but can get complex in a hurry. This is still on my to-do list, but a channel poll resulted in the new input system being a higher priority. As for full on multi-threading. Again, I've just done the basics. For a prototype that I shelved, I was working on a weather simulation that needed to be off the main thread. I think for big calculations this is definitely the way to go, short of Unity jobs systems being production ready. It's a challenge to use as Unity isn't thread-safe so you have to bundle the info, ship it off to a thread, and then deal with the data coming back asynchronously. I actually had a lot of fun putting that system together. Hmm. It could be interesting to put together a follow-up video on the downsides of coroutines.
@@OneWheelStudio Thank you so much for the wonderfully detailed answer :) I think I will keep these in mind and if someone higher than me makes the choice to ditch coroutines then they'll just tell me what to use instead haha! Otherwise, I will continue to use them where (I feel) they make sense.
I’d love to hear more about the specific issues developers have seen. Are these AAA style games with great optimization and complex mechanics or are even same Indie studios struggling with them too.
The second request is pretty easy ;) I'm not so sure about a Bolt video. I have two more Bolt videos in mind, but that is likely the end of the line for me with Bolt... Sorry.
Unity has chosen to take the tool in a different direction with the cancelation of Bolt 2. At the moment I don't see it as a complete tool for creating and finishing a game. It's great for learning Unity and creating small games, but I truly believe most games will hit the limit of what Bolt can do and leave folks needing more. I wrote up a blog post with more of my thoughts if you're so inclined: onewheelstudio.com/blog/2021/4/29/boltvscsharp
I honestly have no idea. I wouldn't be surprised if it went either way. You'd have to test it or maybe ask over on the Bolt (Unity Visual Scripting) discord.
@@homemacai I've honeslt become less and less of a fan of Bolt over the last year. A great tool to get started with. Not a great tooll to finish a game - IMO of course - just too many missing pieces to make it scale well as a project grows.
@@OneWheelStudio For sure, I actually went on rabbit hole of visual scripting this past week, and just now begun using UNode, which seems to me the ideal visual scripting solution, making 1:1 C# code from the visual script and vice versa, was a bit sad on how little information there is about it out there so far, but I do believe it is a game changer for me at least, as I am a designer a and not a programmer. If possible take a look at it sometime, there are some 3 or 4 official tutorials in youtube which give a nice overview of what is possible. But I think with your knowledge, maybe a video would happen about it some day. Cheers!
I looked at it a few months back. To be honest I didn’t think it was polished enough to make a positive and constructive video. I did see they’ve released version 2.x (I think) so maybe it’s better?
hi dear . could you help me ? no one from others youtubers help me. i want to make a 2D puzzle game like LIMBO using BOLT. i created assets and animations and all things. but i have many problems. and i need a tutorial for those things. i dont know how to make a diffirents actions with animations in diffirent places ( i mean , a diffirent player animation while climing on rob, and diffirentS deaths..death when sinking and a new animation death when falling and other animation death when the player touch a saw ...you know ) and i dont know how i can pick up a stone to the player and still that stone in player hand with that animation , and how i can throw the stone to a trap ... i cant write a scripts so for that im using BOLT . but iam a new user in unity and bolt .. so please help me if can!. just a small video try to make two things and i can use same things in the others
What you are asking or trying to do is a big chunk and really doesn't fit into a single or even 2 or 3 videos. The key to tackling these problems is breaking them down in to smaller tasks or chunks and learning how to do each of those separately and THEN combine them. For example you might spend some time looking into triggering animations. Learning how the animator works and how to set animator parameters with code. Dream big, but start small.
Hi . I cant get my coroutine to work . I am changing a colour of a sprite and 1 sec later changing it to another. private IEnumerator WaitAndPrint() { collision2D.collider.gameObject.GetComponent().color = flash; Debug.Log("test2"); //collision.collider.gameObject.GetComponent().color = first; yield return new WaitForSecondsRealtime (1f); Debug.Log("test3"); } When I call it , it never displays test3 . what I am doing wrong ? the coroutine is called within a OnCollisionEnter2D routine whihch sets the colour first.
Hmm. Is there an error being thrown during playmode? A null reference error? Another thought that comes to mind, is the "OnCollisionEnter2D" getting called?
@@OneWheelStudio no errors all works as inteneded except the changing color. I can change the color but cannot get it to pause before changing to the second color. I am using unity 2020.3.0f1 . thanks for responding
@@OneWheelStudio thats what i thought I have tried that. thats way i had the test printed in log . test3 is never printed and in all docs i have seen it supposed to be there
Yeah that is really strange. That’s the behavior I’d expect if an error was being thrown. Happy to help more but might be easier on the OWS discord. If you want to share some code screenshots and maybe the inspector for the object that could be helpful.
I learnt from top 5 reasons your platformer sucks a great method for jump input. By instead of checking the press you have a small timer where for 0.2s it counts as a jump. But I changed his code to use a Coroutine. jumping = true; yield return new WaitForSeconds(jumpTime); jumping = false; Now I didn't need to have a separate variable for a timer and don't need to directly count down by Time.deltaTime.
Just going to say, completely sincerely, listening to your explanations is a breath of fresh air between being drowned by a LOT of other people's confusing babble. Thank you for your content
Fantastic video! Other vids I'd seen left out the "why" and "how", but you nailed it. Appreciated the clarification re: multi-threading.
Thank you so much for the explanation. It was the most clear and concice explanation I've ever seen on this topic.
Thank you. I needed a more detailed, comprehensive infos about coroutines and this video helped a lot. Thanks
Glad it was helpful!
This video is gold literally.
Thanks for the video, I didn't really have a good idea of a nice practical way to use coroutines until you mentioned the idea of something that does not need updated every frame as an example.
Glad it was useful! I don't use them a lot, but they can be very handy.
Good stuff. Thanks. Will probably watch a few more times to try and absorb everything.
Thanks for covering another important topic.
Thanks for nice and detailed explanation... Hope to see more of such explanatory videos coming.
One of the best explanations I have seen so far!
Huh, coroutines look awfully similar to interrupts, but instead of calling a function like interrupts do, it resumes execution.
Thanks for this video, I now understand coroutines. Took me a while to get it!
Thank you so much. I've been having so much trouble with co-routines recently.
Thank you, Exactly What I have been looking for tonight
What an amazing tutorial about coroutines, thanks a lot sir, that's an immediate sub!
Holy shit...such an amazing video, straight to the point and then some. Feels very professional, thanks!
Excellent video. Making similar ones for any other unity-specific classes & patterns would absolutely be successful for you & useful for the audience. Based on the related videos it looks like you're doing just that, so keep up the great work!
you are the ONLY one that's make for me c# and unity understandable , thanks you from France :D (sorry if my english is bad lol)
That's what I was looking for , hope you the best 🌷
Thank you so much for this video. I'm quite rusty on coding, so I was looking for a quick, concise, and well-delivered refresher. This was exactly what I needed.
Main takeaway for me is that coroutines are sophicticated GOTOs.
Srsly, good introduction.
This is just what I needed, thank you!
Thank you! That's an amazing video, you made all of my questions fly away!
Awesome tutorial, you are a gifted explainer!
Great video, very good description of how they work. My absolute favorite Unity addon is MEC(free version) More Effective Coroutines. I rarely use Unity coroutines.
I’ll have to take a look!
Thank you!! amazing video really learned a lot!
Another great one! How did I not find your channel earlier??! :D
Btw: Lerp functions can (and should) reach their endpoint - but many people use them in another way than they were intended. The intention is do allow a linear interpolation, T, between two values A and B: Lerp(A, B, T).
The interpolation value T should be varied over time (from 0 to 1), to give a linear animation from value A to B over a given timeinterval. If the animation needs to be anything other that linear, the T value can be passed through an easing function (example below).
The method show on your screen, while it is working to give a smooth animation, it does have the drawback of never reaching its target, since it's only ever moving 10% closer to it's target value each time. And thus you need to correct the position after the loop.
Another way to do the animation in the Coroutine, without the post loop correction:
IEnumerator FloatDown()
{
float t = 0.0f;
Vector3 start = transform.postition;
Vector3 end = startPosition; // the original cached startPosition is where we want to end up.
while(t
Oh yeah it was driving me nuts seeing him say "A LeRp cAn nEveR rEaCh iTs EndPOinT"
Thanks for taking your time writing the example!
Thank you for this video. The info was good and well explained and I liked your board example
Love your work very methodical, Thank you much appreciated.
Great video. Absolutely clear and demystified the whole concept for me. PS. loosen up that noise gate on your mic!
The perfect way to design a learning material. Great job! I am sure you are going to be big. Good luck 👍
Thanks a lot!
Thank you for creating this tutorial! Overall the concept and implementation of coroutines are good as shown in the video. But I have a small complain, try make your voice louder in the next video. THank you!
Amazing explanation man
Dude! This is fantastic, thank you! Great presentation and explanation, I think I get coroutines now.
Thanks man
Excellent video, I really wish Unity had more detailed documentation about yield Instructions and what they do for unity...if I'm mistaken I'd welcome someone to correct me but apart from some very basic descriptions of waitforseconds and waitforfixedupdate there isn't much else? So having a video like this to explain them more is really useful.
omg thx so much!!!!! really well made video!!!!!!!!!!
Thanks For The content you really helped me out :) stright to the point without overloading peoples minds
This is a great video!
I've never used a coroutine, but this video sure makes me want to! One way to get a value out of a coroutine could be to pass it a generic class that simply has a bool and a value of the generic as fields. The bool would be whether or not it's done or "returned," the the value is of course the return value. This way, you can store the class as a variable or field and pass it as a parameter to a coroutine in another class.
Also about the counter using coroutines, if the coroutine waits for 1 second, then does some stuff, then won't it repeat a little longer than every second? Wouldn't this add up, and if so, how quickly? I would imagine if you're doing simple calculations it would be pretty negligible, but with more complex calculations or over a large timescale, this may add up. A way around this may be to store the value of when the first/previous loop happened and then do some calculation to offset the time to get a more accurate second.
Good video, Can you do an video on delegates and events?
Yep! Here you go: ua-cam.com/video/UWMmib1RYFE/v-deo.html
Coroutines Blog Post: onewheelstudio.com/blog/2021/2/12/unity-coroutines
Project Files: github.com/onewheelstudio/Adventures-in-C-Sharp/tree/main/Coroutines
My basic mistake is that, i thought coroutine is just same like update function but coroutine is more precise because it use second, i have no idea that the variable inside coroutine isn't restarting
Dear One Wheel Studio,
Someone on Discord told me this is the process to make a player with a slider health bar take damage from a zombie enemy at close range, 4.0 stopping distance away.
The zombie has an attack trigger in bolt also, to use an attack animation from Mixamo.
Is this the correct process?
He Say "Ok, so for your health bar here's the things you need to solve in Bolt."
1. You need a variable to store the player's health. It should be an application variable so it's visible to all flow machines.
2. You need a custom event for the zombie to call.
When the zombie attack animation plays => call a custom event "PlayerCheck".
Build the custom event for PlayerCheck.
In it you want to check the distance between the current zombie and the player. If it's less than 4, decrease the health variable by 20%.
That all seems reasonable. Sounds like it would work to me.
Oh and just for the record. I love the comments. They help with the algorithm for sure. But you’re also welcome to jump on the OWS discord - links in the description
@@OneWheelStudio ok ill look for you there, thanks🙋♂️🌠🌠🥳🥳🏝🏝🏝
@@OneWheelStudio What server are you in on discord? How can I message you there? Do you have. a link to your discord?
There should be a link to the “OWS” discord in just about every video description.
I noticed you haven't done any videos on Visual Scripting in a long time -- what are your thoughts on it now that it is a part of Unity?
To be honest, the cancelation of Bolt 2 very much took the wind out of my sails in terms of making Bolt video content and frankly almost all things Bolt related. I thought Bolt 2 was the path to making VS a viable tool for small production worthy games. Not AAA games or even III games, but small games made by a team of just a few people or a hobby solo developer.
As is, I think Bolt or other VS tools are great at onboarding people to Unity - I can't speak to other game engines. And truthfully, I think that is what Unity sees too. It's a way to get more users and as a result, generate more revenue. And that is more than okay! It's an easier way to get started than C#. It's a gentler way to learn the ins and outs of the game engine. I think it's great for simple prototypes or maybe even a game jam.
However, once a project gets beyond the prototype phase I think the shine of VS will wear off. That's what I found personally and with my students - I've used playmaker and Bolt for a total of 5 years in the classroom (I switched to C# this year). Bolt simply doesn't scale well. The lack of classes, functions, events and scriptable objects (all of which Bolt 2 supported) makes it tricky at best to make a complete and polished game. My current project is "simple" and I can not imagine making it with Bolt or other VS tools.
Okay, that's a bit long and maybe more than you wanted ;) This topic has been in my head for a while and I even made a rough draft of a video on it... I never published it as I didn't think it would truly help anyone.
@@OneWheelStudio This was a great reply! (not long-winded) I really appreciate the insight. Perhaps Unity's Visual Scripting (formerly Bolt) will eventually have the features Bolt 2 would have.... but it sounds like, regardless, C# is the way to go.
@@OneWheelStudio I really think a video on the state of visual scripting would be amazing, not sure it would be a positive video, but like Shocktor asked, i believe that many of us are in the Bolt limbo, and maybe a nice way of telling us how to fully abandon bolt, or maybe use it only for what it is good for and integrating with C#. Currently I am using bolt for my project and can say it is going fine for some parts, but others i have to use C# to make it work, and frequently try to move the logic to C# or a mix of both, a but messy but it does work, so far...
@@homemacai I've thought about it. Even done a few dry runs. I wasn't convinced it was constructive...
I did finally write up a blog post with my thoughts. I'm still not convinced it would be a constructive video. You can read it here. But maybe? onewheelstudio.com/blog/2021/4/29/boltvscsharp
2:44 you think my pc has more than 1 frame per second or something lol
Caching the wait for seconds on start is also a good idea in order to save Garbage collector as far as I know right? oh nvm you already mentioned it n.n
Definitely, yes it is! If you are using it to replace an update function this is particularly helpful as otherwise you'd be creating garbage on a regular basis.
Really informative. I do have a question however. I was browsing Unity forums and saw a handful of people say Coroutines aren't very performant and bad for memory, suggesting they should be avoided. I was wondering if this is true and if so, when is the right places to use them versus coming up with a different solution. Thanks.
I have never had a performance issue with coroutines. If you're trying to make the next esports title then yeah you should worry about everything. If you're just making a game for fun or even a small "commerical indie game" and need something to happen in asynchronous way then use coroutines. I use them fairly generously and there are far bigger bottlenecks in my projects.
That said TaroDev has 2 videos on async functions that are pretty great. If you are using Unity 2023 then async functions look to be better than coroutines in just about everyway. With the new features Unity added in 2023 async functions are easy to use and have lost just about all of their downsides.
Hope that helps.
@@OneWheelStudioThanks for the response. This will definitely help.
Some great advice. Personally, rather than caching a coroutine and doing a null check (which from my understanding is a deceptively expensive operation that dives deep into the C++ side), I simply do a boolean check.
When a coroutine starts, set MyCoroutineIsRunning = true and check against that instead.
Did you ever make a video covering the async functions? I often here they are the better cousins of coroutines
No I haven't yet. It's on my list, but there are a lot of pitfalls if the use gets remotely sophisticated. Which I suspect is why there aren't a ton of videos on the topic. If I can come up with a reasonable scope for the video I'll make it happen.
Overly long lasting coroutines can affect performance.
But when you set for it to pause until a certain condition is true. Does that also affect performance the same way or does pausing it let it exist without performance lost as long as it isn't running.
He means LIFO when he says FIFO if your confused for clarification.
Yes. This.
This fabulous tutorial is very compact and informative! Thank your so much!
Your video is amazing, I watch few other videos about coroutines but you explain this very good. Thank you, you have a like and a sub from me. :)
im trying to create a game (old school jacks game, like knuckles), i need to calculate when the ball hits the ground two times, to turn a method off and replace it with a new method. im not sure where to start, is Coroutines a good place?
Thank you for this video. But can we use a starcoroutine in a class and a method with ienumerator that comes from another class? I try but the results are chaotic.
Yes I believe you can. I don’t love that approach and have worked to not do that but as far as I know it works.
does the cached reference to a StartCoroutine(method()) returns null itself after the task has been completed?
That's a great question. I'm honestly not sure. I would guess that the garbage collection would clear out the reference once it's no longer in use... but that's just a guess.
I wrote a short test program. Looks like my guess was wrong. The coroutine reference does not return to null. Interesting!
public class ReferenceTest : MonoBehaviour
{
Coroutine coroutine;
// Start is called before the first frame update
void Start()
{
coroutine = StartCoroutine(SomeCoroutine());
}
// Update is called once per frame
void Update()
{
if (coroutine == null)
Debug.Log("Coroutine is null");
else
Debug.Log("Coroutine is not null");
}
IEnumerator SomeCoroutine()
{
yield return new WaitForSeconds(2f);
}
}
Hi! Great video! I had a question regarding the timer. If we wanted to display the timer in the form of min : sec . milliseconds (0: 00.00) would this strategy still be viable/ improve performance? We could achieve this I think by changing countTime to 0.0001f but then wouldn't our coroutine be less efficient as it would run 1000 times every second? Is there a way to use coroutines for this use case or would it be better to just keep something like that in an update function? Thank you!
The idea is to cache the "wait" statements. They cause some garbage collection. So if you are replacing an Update with a coroutine, then it can be good to cache the "wait" rather than create a new instance every time the coroutine runs. This is more important the more often the coroutine runs.
@@OneWheelStudio gotcha! then for the timer use case coroutines would be a bad idea as it would require them to run more often?
What is the "timer case?" Sorry if its in the video, it's been a while :)
@@OneWheelStudio the use case you demonstrated in the video at timestamp 2:42. I am just wondering if you wanted to output a timer using the minutes: seconds.milliseconds format if you could potentially use a coroutine with something like WaitForSeconds(0.001f) and update time every millisecond? Or is that not the right way of approaching such a problem
I guess it really depends how fast you want the timer to update. I would think if you want it super fast, an update function would be the way to go. The example I showed it as an optimization if you only want it to update every second.
start coroutine could not be found
what I have to do to fix that
Hmmm. Sounds like maybe autocomplete is not playing nice. That can be a tricky one. But try a search for "Unity autocomplete not working." Sorry wish I could be more helpful than that.
Hey @OneWheelStudio, what are your thoughts on using Coroutines in Unity?
I have been working as a Unity Dev for about 2 years now, and it seems companies really don't like using Coroutines for stability, garbage collection, etc.
When would you consider an alternative like async or mult-threaded solutions as opposed to Coroutines?
Hmm. Interesting. I've heard other folks mumble about coroutines not being ideal. Truthfully, I don't use them that often in my personal projects. I did when I first got started with Unity - they were everywhere! They're so easy right!?!
My personal project mostly makes use of actions/events to trigger things far more so than coroutines. For so many reasons this is my preferred way to wire things ups. I do use DoTween to polish and juice things up - and I think/suspect that is based on coroutines in the background.
There definitely can be some garbage collection issues with coroutines - I'm mostly aware of the issue with the wait statements. Which in some cases can be dealt with by caching the wait statement, but I can imagine there could be more.
The lifetime of a coroutine is also something that needs to be carefully managed which could lead to some stability issues. I'd be curious to know what other stability issues developers have run into.
As for async functions, I have used them, particularly when implementing Facepunch Steamworks. I've done the research to put a video together, but honestly, I was struggling to come up with a general enough use case for a good tutorial. Requesting information from a server (i.e. steamworks) is a great use case for async functions, but for my channel's viewers, I was struggling for something more general. My impression is they are very powerful, not too hard to use at a basic level but can get complex in a hurry. This is still on my to-do list, but a channel poll resulted in the new input system being a higher priority.
As for full on multi-threading. Again, I've just done the basics. For a prototype that I shelved, I was working on a weather simulation that needed to be off the main thread. I think for big calculations this is definitely the way to go, short of Unity jobs systems being production ready. It's a challenge to use as Unity isn't thread-safe so you have to bundle the info, ship it off to a thread, and then deal with the data coming back asynchronously. I actually had a lot of fun putting that system together.
Hmm. It could be interesting to put together a follow-up video on the downsides of coroutines.
@@OneWheelStudio Thank you so much for the wonderfully detailed answer :) I think I will keep these in mind and if someone higher than me makes the choice to ditch coroutines then they'll just tell me what to use instead haha! Otherwise, I will continue to use them where (I feel) they make sense.
I’d love to hear more about the specific issues developers have seen. Are these AAA style games with great optimization and complex mechanics or are even same Indie studios struggling with them too.
Can you please make a coroutine video for Bolt ?
and re-write this line: "Buy a Game Design Books:......"
The second request is pretty easy ;)
I'm not so sure about a Bolt video. I have two more Bolt videos in mind, but that is likely the end of the line for me with Bolt... Sorry.
@@OneWheelStudio No more bolt videos ? Why ?
Unity has chosen to take the tool in a different direction with the cancelation of Bolt 2. At the moment I don't see it as a complete tool for creating and finishing a game. It's great for learning Unity and creating small games, but I truly believe most games will hit the limit of what Bolt can do and leave folks needing more. I wrote up a blog post with more of my thoughts if you're so inclined: onewheelstudio.com/blog/2021/4/29/boltvscsharp
Very nice explanation! Do you think that Bolt coroutines, stop themselves in the right time when not being used?
I honestly have no idea. I wouldn't be surprised if it went either way. You'd have to test it or maybe ask over on the Bolt (Unity Visual Scripting) discord.
@@OneWheelStudio I think it's better to use C# Coroutines! Your video explains very well, no reason not to try doing it myself! thanks!
@@homemacai I've honeslt become less and less of a fan of Bolt over the last year. A great tool to get started with. Not a great tooll to finish a game - IMO of course - just too many missing pieces to make it scale well as a project grows.
@@OneWheelStudio For sure, I actually went on rabbit hole of visual scripting this past week, and just now begun using UNode, which seems to me the ideal visual scripting solution, making 1:1 C# code from the visual script and vice versa, was a bit sad on how little information there is about it out there so far, but I do believe it is a game changer for me at least, as I am a designer a and not a programmer. If possible take a look at it sometime, there are some 3 or 4 official tutorials in youtube which give a nice overview of what is possible. But I think with your knowledge, maybe a video would happen about it some day. Cheers!
I looked at it a few months back. To be honest I didn’t think it was polished enough to make a positive and constructive video. I did see they’ve released version 2.x (I think) so maybe it’s better?
hi dear . could you help me ? no one from others youtubers help me.
i want to make a 2D puzzle game like LIMBO using BOLT. i created assets and animations and all things.
but i have many problems. and i need a tutorial for those things.
i dont know how to make a diffirents actions with animations in diffirent places ( i mean , a diffirent player animation while climing on rob, and diffirentS deaths..death when sinking and a new animation death when falling and other animation death when the player touch a saw ...you know )
and i dont know how i can pick up a stone to the player and still that stone in player hand with that animation , and how i can throw the stone to a trap ...
i cant write a scripts so for that im using BOLT . but iam a new user in unity and bolt .. so please help me if can!. just a small video try to make two things and i can use same things in the others
What you are asking or trying to do is a big chunk and really doesn't fit into a single or even 2 or 3 videos. The key to tackling these problems is breaking them down in to smaller tasks or chunks and learning how to do each of those separately and THEN combine them. For example you might spend some time looking into triggering animations. Learning how the animator works and how to set animator parameters with code. Dream big, but start small.
@@OneWheelStudio i know this things, but i watch many many tutorials and i cnt find what i want :'( . anyway thanks .
Hi . I cant get my coroutine to work . I am changing a colour of a sprite and 1 sec later changing it to another.
private IEnumerator WaitAndPrint()
{
collision2D.collider.gameObject.GetComponent().color = flash;
Debug.Log("test2");
//collision.collider.gameObject.GetComponent().color = first;
yield return new WaitForSecondsRealtime (1f);
Debug.Log("test3");
}
When I call it , it never displays test3 . what I am doing wrong ? the coroutine is called within a OnCollisionEnter2D routine whihch sets the colour first.
Hmm. Is there an error being thrown during playmode? A null reference error? Another thought that comes to mind, is the "OnCollisionEnter2D" getting called?
@@OneWheelStudio no errors all works as inteneded except the changing color. I can change the color but cannot get it to pause before changing to the second color. I am using unity 2020.3.0f1 . thanks for responding
Oh ok. Looks like you wait for seconds is too far down in the coroutine. It should be between the color changes. If I’m reading this right?
@@OneWheelStudio thats what i thought I have tried that. thats way i had the test printed in log . test3 is never printed and in all docs i have seen it supposed to be there
Yeah that is really strange. That’s the behavior I’d expect if an error was being thrown. Happy to help more but might be easier on the OWS discord. If you want to share some code screenshots and maybe the inspector for the object that could be helpful.
I learnt from top 5 reasons your platformer sucks a great method for jump input. By instead of checking the press you have a small timer where for 0.2s it counts as a jump.
But I changed his code to use a Coroutine.
jumping = true;
yield return new WaitForSeconds(jumpTime);
jumping = false;
Now I didn't need to have a separate variable for a timer and don't need to directly count down by Time.deltaTime.
Look, I've completed some coding tutorials, okay? Whatever it is I'll understand.
There's nothing about this I understand