Coroutines in Unity (how & when to use them)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you're just getting started in unity then it's likely that so far you've been putting most of your game's logic in update which is called every frame which for behaviors that take place during each frame is absolutely fine however only using update can make it tricky to manage logic that happens over an extended period of time for example if you want to fade something in or fade something out or if you want to perform a series of tasks one after the other or if you want to stall a function for a number of seconds trying to do that inside of update can be very difficult but there's an easier way by using a co routine in this video you'll learn what a co-routine is how it works and when you should use one so what exactly is a co-routine in unity unlike update which processes code on a by frame basis a co-routine in unity allows you to execute game logic over a number of frames this works because coroutines unlike regular functions are able to pause their operation until the next frame allowing you to split a function's logic into a number of steps that take place over a period of time instead of all at once but how is this useful let's say that i want to give an object a series of instructions such as this tank for example what if when i click on the map i want the tank to turn to face where i've clicked move to that position wait a second then fire it's entirely possible to do this in update but it can be very tricky in update each frame is new so to do something over a number of frames typically involves finding a way to keep track of what has already happened and what needs to happen next meaning that if i want to process a series of steps in update i'd need to use different boolean values just so i knew which step the tank was on right now and while it's possible to work like that it can be unintuitive and inefficient a co-routine however works kind of like a to-do list unity executes the coroutine function in order just like a regular method in update except that unlike update it's able to pause what it's doing during one frame and pick up where it left off in the next which can make it much much easier to execute a series of actions in order so how do you write a code routine in unity co routines are created using the i enumerator return type followed by the name of the function and any data you want to allow to be passed in variables you create inside the co-routine will persist for its duration meaning that just like cached variables at the top of a class variables in a coroutine can be used over a period of time the main difference between a coroutine and a regular function is that a core routine can be suspended between frames allowing you to create functionality that takes place over a period of time this works by using different types of yield statements which allow you to instruct the co routine to stop what it's doing until the next frame five seconds later or until something else has happened after which the co routine will continue where it left off so what are the different types of yield statement one of the most common yield statements you're likely to use is yield return null which suspends execution of a core routine until the next frame when used inside of a conditional statement yield return null can be used to create many update loops inside of co routines what's happening here is that the while loop is processed over and over until the conditional statement is no longer true allowing the rest of the code if there is any to be executed now if you were to do this in update without yield return null it would all happen in the same frame what's different in a co routine is that the yield statement interrupts the function and pauses it until the next frame so the function still works in exactly the same way except the logic is split over a number of frames instead of one this is useful as it allows you to create multiple conditional loops that can be run one after the other going back to the tank example this is ideal for turning the tank until it's in position then moving it afterwards until it reaches its target point then once the tank reaches its position if i want to wait for a second before doing anything else i can by using weight for seconds wait for seconds or wait for seconds real time which uses unscaled time is an easy way to delay a function by a number of seconds while it's running to use it simply type yield return new wait for seconds and then pass in the amount of time you want the function to wait for in seconds then instead of pausing until the next frame the co routine will wait for a number of seconds before proceeding again it's entirely possible to do something like this in update instead of using a co routine you can delay the start of a function using invoke or it's possible to repeat a function using invoke repeating or to pause a function halfway through you could create a timer and measure an amount of time using delta time in a similar way to wait for seconds however if you need to pause a function for an amount of time chances are it's because you want to do one thing wait a moment and then do something else which in update where everything happens all at once can be much harder to manage whereas because a co-routine remembers where it was performing sequential tasks with gaps in between can be much easier to do in a co routine other yield statements include wait for end of frame which will suspend the co routine function until the end of the frame event message is called why would you want to do that while update and even late update both happen before rendering using wait for end of frame will suspend the function until after the scene is rendered this can be useful for making sure the frame is actually finished before doing something with the image such as taking a screenshot there's also the wait until and wait while statements which work in a similar way to using a while loop with a yield return null statement except that they allow you to use a delegate function in place of a conditional check or it's possible to make one co-routine wait for another using yield return start co-routine allows you to wait while another co-routine completes after which the co-routine that called it will continue from where it left off however if you're going to start a co-routine inside of another co-routine now would probably be a good time to explain how to start one there are two main ways of starting a co-routine you can start a co-routine using its string by passing in the name of the co routine that you want to trigger this optionally will allow you to pass in one parameter into the coroutine function or you can start a co routine by referencing it directly in the same way that you would call a function and in most cases this is generally the better way to do it this is because it's slightly more efficient to do it this way and it also allows you to cache a reference to the co routine you just started so this works by declaring a coordinate variable and setting it with the start coroutine function which will both start the co routine and cache reference to it which can be useful when you want to stop it how do you stop a co-routine a co-routine will stop automatically once it reaches the end of its code so there's no need to explicitly stop a co-routine unless you want to cancel it or end it early in which case there are two main ways to do that externally or from within the co routine itself using yield break from inside the co routine will end it on that line which can be useful for creating conditions within the co-routine function that could be used to exit out of it when you start writing a co-routine you'll usually see an error straight away informing you that not all code paths return a value this is because of the return type of a co routine but put simply it just means that you will need to use a yield statement at some point in your code which makes sense because if you're not suspending the function in some way there's no point in using a co routine anyway if you'd like to avoid this error while you're writing the code routine just add yield break to the end of your code remember however there's no need to add this since a coroutine will end when it reaches the end of its code block anyway it's just a simple way of hiding the error while you're writing the code if you want to cancel a curry scene externally the stop co routine function is one way to do that so just type stop co routine and pass in the curry scene you want to stop you might typically use this before triggering a co-routine as if there's a chance that the curating you want to start is already running stop co-routine can prevent you from triggering multiple instances of the same ko routine however this only works if you have a reference to the co routine that's running and only if that reference has been set otherwise you'll get a null error so to prevent that i can just wrap this in an if condition in some cases however it can simply be easier just to stop everything using the stop all co-routines function stop all co-routines will stop any and all curry scenes that were triggered by the script that it is used on meaning that it won't affect other co-routines in your game only the ones that were called by the script that you trigger the function on but what about if you call a co routine in another script stop all co routines applies to the script that triggered the co routine not the script that the co routine itself is written in so for example if you use one script to start a co routine from a different script using stop all co-routines on the first script will stop it while using it on the second script won't stop anything this happens because co-routines are tied to the script that first triggered them for example destroying the object that started the co routine will end it but destroying the object with the script that the co routine is written in won't whenever you want to break up a function so it takes place over a number of frames or over a period of time a co routine is usually going to be a good option for doing that however while they can be very useful for their intended purpose they can sometimes be more trouble than their worth if you try to use them in the wrong way so what's the best way to use co-routines most of the time it's a good idea to avoid overlapping co-routines just like with any function it's possible to trigger multiple co-routines of the same type so that several are running all at once however unless this is the behavior you want triggering multiple co-routines can be confusing and if your current team is designed to do something to just one object such as fade it in or move it for example accidentally running more than one at the same time is going to cause you problems for this reason if your core routine is designed to be used one at a time it's usually a good idea to stop all co-routines before starting a new one secondly co-routines work best as set and forget functions what does that mean it means that while co-routines are good for staging a function over a period of time they're not a great fit for dynamic functionality that changes in response to other factors such as artificial intelligence for example take the tank example from earlier in this video a co-routine works with this because it's a linear function staged over a period of time when the player clicks the tank turns then moves then waits then fires however if the tank was controlled by an ai that would sometimes turn move wait or fire depending on the actions of the player then a co-routine probably isn't a good fit for that and you may be better off with some kind of behavior tree or state machine instead put simply co-routines are still linear functions they just happen over an extended period of time lastly while co-routines can be great for splitting logic up across frames it's not the only method for doing that async awaits in unity allows you to perform tasks asynchronously and while the results can be similar it's a different kind of workflow to co-routines co-routines work like any other function the only difference is that they have stopping points that suspend their operation between frames asynchronous operations however work in the background parallel to other tasks one of the main practical differences of async awaits when compared to co-routines is that co-routines can't return data but a sync await can practically this makes a sync awaits more suitable for managing multiple tasks at once whether that's sequentially so one after the other or in parallel where you might trigger multiple tasks at the same time for more information on async await and when you might use it see the link in the video description so now i want to hear from you do you use co-routines in your game have they helped you or have they caused more problems than they've solved and what's your best co-routines advice that you know others will find helpful whatever it is let me know by leaving a comment below remember to like this video if you found it useful and get subscribed for more videos from me i'll see you next time you
Info
Channel: Game Dev Beginner
Views: 16,400
Rating: undefined out of 5
Keywords:
Id: kUP6OK36nrM
Channel Id: undefined
Length: 12min 35sec (755 seconds)
Published: Fri Jun 10 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.