How do you understand IEnumerators?

What are some good uses for them? What makes them appropriate?

Share your challenge solutions here.

Im so pleased to see others using food for analogys. People at work are real sick of my food analogies :smiley:

thankfully IEnumorators have meant something to me for a long time, along with the whoile yield return and so on.

2 Likes

I laughed a lot during that lesson. :slight_smile:
I haven’t used IEnumerators or Coroutines much before, but a few of the applications of them I can think of are:
pausing an NPC’s behavior until a criteria is fulfilled, or timer (Replacing dwellTimeAtWaypoint?)
Hmmm… I’m having trouble thinking of examples that couldn’t also be solved by using a float that counts up/down in the Update function. How do IEnumerators/Coroutines differ from that functionality?

1 Like

One good way to use IEnumerators is to read in data from one area which takes a time to generate them, such as finding prime numbers, and you can return them as you find them

1 Like

Would an IEnumerator be used in a card game scenario, as in to take the top card from a deck? similar to the top chip in your analogy? or am i missing the point on this?

It could be. Even more useful. If you have an array of cards and you want to take one out randomly repeatedly you could create an IEnumerator that would lazily pick a card at random and remove it from the array. This could be used to simulate a shuffled deck.

I understand that they are a type of array which we can have access to any part of it and can store unique values(This opposed to a Stack where its generic and you only can take the top). They are a bit heavier on the system to deal with correct? I was looking at using one of these for the deck of the card game I am making. I figure a deck load out screen will have to be editing where the player will be able to access a view of their database which would be manipulating/building their IEnumerator, which would be stored in the database, under their profile data correct? Is an asset bundle the best way of passing this data from one scene to the next? Another use of IEnumerator would be for storing states of things? Such as if I want those cards to go through an upgradable process? or would this be better suited under a different way?
I would imagine the T-Stack to be more edible… :thinking:.

The IEnumerator is more like a stack in that you can only access it one at a time. It cannot be expensive in itself because it is just an interface. You can implement it with an array or with a list or even calculate the values as you go (like the fibonacci example from above).

I was thinking of the combat system in Knights of the Old Republic. You could queue actions like attacks or using items, and they would happen in order, pausing for a a certain amount of time elapsed.

1 Like

Any kind of cool down for example. Weapon reload, mana charge, explosive timer, sprint cool down, health regeneration, time between attacks like if the player had a heavy weapon like an axe.

Changing gears in a racing game, Maybe at the start of a race when the counter is going down 3, 2, 1.

1 Like

I have used coroutines often before, but did not really get into the theory of how they worked and when using them would be most effective, I used them mainly when they were required by another function or class. If I am following the logic here, there are a lot of reasons we could want to use coroutines. Here are a few situations where I am thinking they would be useful:

  • Games with continuous waves need new enemies to spawn only after previous ones have been defeated or after a time interval.
  • A player can only use a special item like a potion or a spell after a cooldown period from the last time they used/cast it.
  • Many phone-games now have stamina-bars or energy-points that regenerate every few minutes and/or buildings/workers that generate income/resources every so often.
  • Asset loading/preloading could be another place to do this if you want the player to be able to play the game while things are loading in the background in preparation of the next gameplay moment.

If I am not mistaken the IEnumerator is a part of a Design Pattern, and needs to be used in conjunction with a IEnumeratable. The idea being that you create some sort of Data Structure that you would like to be able to iterate over in a meaningful way. You user the IEnumerator to make create that meaning. This is a huge simplification of the topic, and I am not doing it justice.

I think the yield return is just a build in construct that uses the Enumerator Pattern to unroll a loop for asynchronous access.

The best explanation I have ever heard was from a guy called Nelson LaQuet from the site 3dBuzz.com. To bad the guy running that site got sick because I dont think they keep that site up any more. However, the C# 102 - Spring 2012 and the C# 103 are awesome, he stresses good design and architechure and gives his examples via that spotlight. The bad it is a recorded online lecture format so it is long and not well sectioned but some of the best info I have ever heard on C#.

1 Like

IEnumerator reminds me of a stack or it is part of a stack. Stacks are used to setup a list of instruction in assembly if my memory serves me right. So anything that is stack and can be pulled and called. Example might be a dialog with a stack of strings that you are going over or voice files. Maybe something like a magic deck of cards, that one is drawn and destroyed and another is called until empty. Ammo types. Any kind of limited special container types like the example with the Pringles. Because it can yield something can be drawn wait for use and a call for another item.

Good example. One more thing that IEnumerators can do is lazily produce the value. So unlike a stack that requires everything to be placed on it already. So Stacks are IEnumerators but not all IEnumerators are Stacks.

I’ve used coroutines for boss battles before, special for generic behaviour, like wait until certain condition (current health, time, player position) to start next phase or to perform certain attack/animation/eatAPringle/whatever.

1 Like

Love it. Great example.

I liked the pringles example - sausage pringles sounds awesome! We don’t have those here.

This sounds exactly like a linux fifo pipe and/or a queue to me. It is kinda like a poor mans threading model where you can unblock the main routine to let the producer produce more data.

True, very similar to pipes. My unix foo isn’t what it used to be so I’m not sure if the two processes in a pipe excecute in parallel but I think they might.

With IEnumerators it’s important to note there is no parallelism just asynchronous execution. All the code can run in a single thread.

1 Like