 To understand Unity's co-routine feature, we first should understand C-sharp's iEnumerator interface. This is an interface where you have two methods, moveNext, taking the arguments and returning boolean, reset, taking the arguments and returning void, and a property called current which returns an object and has no setter. The idea of an iEnumerator is that it's, well, it's an iterator pattern. We have this series of data of some kind, say like an array or some collection, or just some logical series of data we're reading from some data stream, and we want to go through the elements of data one by one. So we have this marker keeping track of where we are in the series, and then we can access the value at that marker and advance the marker. So the current property is how we access the value at the marker, moveNext is how we advance the marker, and this returns true when we've successfully advanced the marker, and this returns false when the marker is already at the last element of the series, and then the reset puts the marker back at the beginning. Though commonly implementers of iEnumerator may not want to implement reset, it may just not make sense for the kind of work they do, and so they will just throw a not implemented exception, though in this case we're actually moving the marker back to the beginning. So in this particular example, this plus two class, the idea is that we construct an instance with an array of ints, store that in this field values, and we have this index to keep track of the marker or place in the array, and then when we access current, it's that value from the array but with two added. So we're not getting exactly the values from the array, we're getting that value plus two. And the reason index starts out with the value negative one rather than zero is because for this interface to access the first value, the convention is that the user should call moveNext first before accessing that first value. So our index starts out at negative one, and then the first time moveNext is called index is incremented to zero. The note in here, we check if index is equal to the last index of the array, and if so, then we return false because we can't advance the index anymore and we're done iterating through the array. Otherwise though, we increment index and return true. So then here's an example of using this class. We have this array of ints called vowels with values 105, negative 12 and 40. We create an instance of plus two without array, and then we call moveNext on the enumerator in a loop, and then after each call to moveNext we access the current value and print it out. So this should print out first 102, 7, negative 10, 42. So let's just see that in action real quick. Let me save the code here, go back into Unity, hit play, and we got 102, 7, negative 10, 42, just like we expected. Now somewhat confusingly, there's an interface called iEnumerable with one method, getEnumerator, which returns an instance of iEnumerator. So for certain kinds of things like say arrays and other collections, they implement this interface because there are things from which you can get an enumerator. In this particular example, plus three, the code is exactly the same as previously, except now we're adding three, and we have the getEnumerator method here, which is going to return this because we've made our iEnumerator also an iEnumerable. They are one and the same thing. In principle, of course, any enumerator could implement iEnumerable this way. Though it's not necessarily commonly done, I just did so for expediency. And so seeing this in action, the thing about enumerables is that they can be used in 4H loops. And so here we can create an instance of plus three, just like we did with plus two, but now we can use 4H and iterate over P3. And so for this loop, we would see printed out 103, 8, negative 9, 43. In addition to the regular iEnumerator interface, we also have a generic version where you specify type parameter here, T. And for the current property, it returns type T. But then for reasons I don't entirely understand, you also have to have iEnumerator.currentProperty, returning regular object. I think this is here for like backwards compatibility, but though I'm not entirely certain, and we're not going to use it anyway, so we're just going to throw not implemented exception if anyone uses this. Also, there's another method you have to implement called dispose. And the idea here is that you would want to dispose of an iterator in case it's holding on to any kind of resources, like say an open file or something. Though I don't know why the generic version has this method, but the non-generic version does not. I think the generic version came later and they decided, oh, enumerators should actually have a dispose method. So I think that is really the only reason. And it's otherwise exactly like a regular enumerator. And in this case, this repeating class, you pass in some array of values of an array of any kind. And this iterator cycles through all the values in the array. And when we get to the end, it cycles back to the start. So this iterator just keeps serving up values from this one array. And it does so in repeating cycles. So in our code, when we use this, well, we don't want to iterate forever because the iterator never ends. So you wouldn't want to have code like this. Instead, we'll just go 15 times and advance the enumerator and access the current value. So this should print out, let's see, 105, negative 1240 and then keep repeating that until we've printed out 15 values. Now, because creating enumerators might be something we want to do quite frequently. C sharp has a convenience in the compiler. It has what we call generator methods. A generator method is a special method in which we use the reserved word yield. And we have yield return statements and yield break statements. The return type for these methods must be either I enumerator or I enumerable, either one. And we can use the generic versions of those interfaces. You'll just use regular enumerator. And what you should understand about these generator methods is that they really aren't methods at all. They're really anonymous classes behind the scenes. The C sharp compiler will look at this and generate an anonymous class whose name we never see. But it's a class implementing I enumerator. And from this code, the compiler figures out what fields the class should have and what the move next method and the current get property accessor should look like. So that's what is actually happening here. But another way to think of it is that these generator methods are like special methods which can suspend their execution and then pick up from where they left off. The yield return statement is what suspends the execution and yield break terminates the execution. So in fact, we don't actually need this yield break statement. This can just be left implicit because of course a method ends implicitly at the end of its body. So anyway, when we call this method, we immediately get back an I enumerator and understand this code does not yet start running. This code does not run until we call move next. So once move next is called, then this code starts executing. And when we hit a yield return, the yield return value is what the current value is set to and move next returns true. The next time we call move next execution resumes at that point continues on until the next yield return or until we hit a yield break. And when we hit the old break current is not set to anything and move next returns false. So this generator method here, what's really happening is the compiler from this code generates a class that looks very much like our plus two class. In fact, I'd be surprised if it looks significantly different at all. It has probably this exact same logic. Except the enumerator returned by a generator method never implements the reset method. If you call reset on those enumerators, they always throw a not implemented exception. But otherwise, the logic in the class would look just like you see here. So a generator method spares us from having to create a class like this. And also in some cases, the logic of your enumerator is perhaps easier to reason about when expressed in this form than as a normal enumerator. But just be clear, these generators are entirely a convenience. You could always instead just create an ordinary class implementing I enumerator. So here to see this in action, we're calling the plus two method. We don't actually have to qualify with this that can be left implicit. We get back an enumerator, we call the move next method, and each time access the current value like with any other enumerator. And in this case, the plus two generator method is giving us back those values but adding two to each. So we should see printed out from this one of two, seven, negative 10 and 42. Here we have the generator equivalent of our repeating class. And it's generic just like the class. And because we want to create an iterator that never stops iterating, we just start off with a infinite loop. And we go through all the values in vowels and yield each value. So when we call this generator, we get back an enumerator in this case of type int. And because this is a iterator, which we can't exhaust, it just goes on forever. We'll iterate a finite number of times, call move next, and then access the current value and print that out. So now we can finally talk about Unity's co routines. What is a co routine? Well, it's a feature of some programming language is not C sharp, there's not a built in language feature. And it's not a feature of any mainstream language I can think of. But the idea is that much like these generators, you can have a function which can suspend its execution and then have that execution resume. Well, Unity calls these things co routines because it achieves a similar effect using enumerators. There is this method start co routine, which is part of mono behavior. So inside here, my script, which is inheriting from a mono behavior, I've access to this method. I call start co routine, and I pass in any I enumerator. In this case, one returned by calling repeating doesn't really matter for our purposes right now. But anyway, so we have some enumerator. And then Unity will take that enumerator and keep calling the move next method by default once per frame. To be precise, in the call to start co routine, it calls move next once. And then the next call to move next the subsequent calls for each subsequent frame. It'll keep calling move next after the update until move next returns false. And then it'll stop calling move next on the enumerator and it just dispenses with the enumerator. In this particular case, repeating returns an enumerator whose move next never returns false. So this will effectively be a so called co routine, which will run indefinitely. But we can also stop execution of a co routine by explicitly calling stop co routine method and passing in the co routine. So start co routine returns a co routine value, which is used for no other purpose except to pass to this method here so that we can stop the co routine. So that's the other way to stop further execution of the move next method of that enumerator. And there's also the stop all co routines method, which will cancel all co routines started from this mono behavior. Be clear that start co routine is a method of a particular mono behavior. And it keeps track of all the co routines currently executing currently scheduled from that amount of behaviors. So calling this method, you don't specify any co routines or just stops all of them started from this particular instance of mono behavior. Now what's a little odd here is that normally with enumerators, the idea is to have something which produces data and we care about what the current value is. But here the idea with the enumerators, which we execute as so called co routines is we don't really care about the values produced the values which are retrieved through the current property. We just want the code to be executed we care about what happens in the move next method. Because in the move next method of these iterators we can do whatever we want just like we can do anything in an update method, we can manipulate the game objects in a scene in any way we choose. So we might use a co routine to have something done for some number of frames like the sum of them repeating business that should be done over some number of frames. And because it's something that's not done for every frame for the whole game at some point we're going to we want to stop and make sense to put that logic into a co routine. So it's something that will happen over some number of frames and eventually stop. So the common use case for these co routines is there's some kind of code we won't have executed say for some number of frames. And then we're done with that business that that business will end. If there's something you want to do every frame for the whole game you put that in an update method but if there's something you want to do say for a limited period and then stop and make sense to put that in a co routine. Now as I just said, with these co routines the real purpose of the iterators is not really to produce data. It's not to produce values read through the current property is to do stuff. But each time after calling move next unity will look at the current value. And if it's an instance of the yield instruction class that yield instruction tells unity when next to run the co routine when to call move next again. By default it's just done in the next frame after the next update. But there are a few different kinds of yield instructions that let us change that the kind of yield instruction we use most commonly is one called wait four seconds which specifies a period of time as a float value. So like 3.2 meaning 3.2 seconds. And when after calling move next of the current value is a wait for seconds values representing say 3.2 seconds. Then rather than calling move next after the update of the next frame unity waits for 3.2 seconds to elapsed before again calling move next. So here for example this recurring pause generator method returns an Ion numerator of type wait for seconds. The current values are going to be wait for seconds values. And in the actual method we have an infinite loop in which we print out the amount of time that's elapsed and how long we're going to pause for which is the value we pass in here. And then each time through we're yielding a wait for seconds value where the elapsed time is F the parameter F of this method. And so up here if we call recurring pause with the argument 3.3 we get an enumerator which every time we call move next prints out a message and sets the current value to waits for seconds with this duration 3.3 seconds. So if I comment all this code out here and comment this we don't need to see throughout that save and I'm going to go run the program. So I play the game and we see printed out the message and it's pausing for 3.3 seconds calls move next again prints out the message pauses for 3.3 seconds move next is called again. So the calls to move next are occurring every 3.3 seconds because each time move next is called it's setting the current value to that yield instruction of type wait for seconds whose time value is 3.3. And so it's waiting for 3.3 seconds till until the next call to move next. Again be clear, we are creating an enumerator passing it to start co routine, which then calls move next the first time immediately in the call here. And that's why immediately we see printed out this message, then it yields and waits for the next call to move next, which is what we see after 3.3 seconds. So wait for seconds is probably the most commonly used yield instruction. There's also wait for seconds real time, which disregards time scaling, which is something you can do to like speed up execution of the game. It basically is like a modifier that changes the reported delta times in your frames that lies about the time to your game logic. So it effectively like speeds it up and slows it down anyway. So this will ignore that if you change the time scaling. Then is wait for fixed update, which causes the next move next to be called in the next physics update of the next frame. So after all the on collision calls, the on collision handling methods, there's also wait for end of frame, which puts the next move next immediately after everything is rendered except just before the frame is displayed on screen. And then we have wait until and wait while, which are logically the opposites of each other wait until you supply a delegate, which is what C sharp basically calls a function pointer. That's what they call them. The delegate predicate function, or I should say method is executed each frame after the update, but before late update. And when it finally evaluates true, then move next is called again, again, wait while is the logical inverse of that. So it waits for the delegate to evaluate false. And then lastly, www. This is the one you use when you started an HTTP request, and you want something to happen in the frame where that request has completed. Lastly, to be clear, if the current value after calling move next, if it's something other than yield instruction, just any value that's not an instance of this class, including just the value null, which is usually what we want. That gets us to default behavior, which schedules move next to be called after update of the next frame. So that's like the default. But then by setting current to one of these yield instructions, we can get something other than that default behavior.