[Unity Game Development Tutorial: 8] - Coding Lesson 4 - Coroutines

in #unity8 years ago

Most tutorials focus on internal Unity Events like Update() or FixedUpdate(). This tutorial is going to focus on how to use Coroutines in some circumstance to improve performance.

Standard Coroutines


Coroutines are a style of method that you setup in C# that can yield operation back to the rest of the code. Consider this. When the Update() event is called in Unity everything in that event is processed before other things can continue. If this extremely task intensive it becomes what is known as Blocking. Nothing else can happen until that event is completed. This can of course be a big issue with many games. (NOTE: You can do coroutines in other languages besides C# in Unity. For more information see this page.)

This means there is some advantage in the ability to build non-blocking routines. That is where the idea of Coroutines come in. Using yield commands you can make methods that essentially get to a point, pause what they are doing as they yield to the rest of the engine, and will resume when the condition of the yield is met. If you are going to do a lot of complex calculations, world building, or similar things a coroutine can be beneficial for that. You can make that world building happen without being blocking.

Here is a verbal description of an example:

Without a Coroutine: You put a progress bar UI element on the screen that you want to fill up gradually as a world builder method builds the game level. You call your world builder method and it BLOCKS the main thread until it is done. Result the progress bar goes from nothing to filled with a long pause (however, long it took to build the world) with no activity. You can fake this by making the world builder more a state engine and only building the world in chunks, and having something like Update() call the world builder until a state is a certain thing. Yet the better approach for something like this is a coroutine.

With a Coroutine: You build the same world builder method. Yet when you have particularly complex tasks that need to be done multiple times you place a simple yield return null in that loop at a point of your choosing. Each time it hits that point it will unblock and return control to other things, such as possibly a progress bar Update() event so your progress bar actually moves, such as player movement, etc. It will return as soon as it has processed a frame. This does slow down how fast your world building method runs, but it doesn't lock the game in terms of everything else. So there may be cases you want to lock. In such cases it is likely best to throw up a static "Please Wait..." style load screen that doesn't need anything to actively change. Then your level builder could be blocking without it drawing too much attention.

Other benefits to Coroutines


Do you truly need something that runs as often as the Update function or FixedUpdate? What if you have a simple method that you need to run every 30 seconds in the game? With FixedUpdate or Update you would need to perform a check every frame to find out if 30 seconds had passed. This would likely end up being thousands of comparisons made and possibly more before the 30 seconds actually occur. Alternatively you could build a coroutine that has a yield return new WaitForSeconds(30); statement in it. It will fire every 30 seconds without needing thousands of calculations. This can have some great performance benefits if you are building some complicated designs.

How do you make a coroutine?


A coroutine must be setup to return the data type IEnumerator. Otherwise it is setup very much like any other method. The method by which a coroutine is called is different.

The coroutine was called from inside the Start event using StartCoroutine().

There are several types of yield statements you can use with Coroutines.

The docs.unity3d.com has a section on coroutines here if you would like to see their various examples.

Example Time System Coroutine


It is pretty popular in games to have day/night time systems. You can setup something like that pretty nicely with coroutines and some public variables so different parts of the game can find out what time it is.

Concerns with coroutines


There are some memory and performance related issues that can arise with coroutines. They are more likely to be an issue if you are calling StartCoroutine many times, and for situations like that. I haven't seen too many of them with my timing and specifically spaced out coroutines that do not call other coroutines.

It has been said that every built in Unity Coroutine allocates Garbage Collector memory every frame. I am assuming this is only for coroutines that are called every frame. You may want to consider this with caution though and I am getting this information from a location that benefits from this being the case. They want you to use their solutions.

There is hope though if you need to use coroutines like this. Again the asset store is to the rescue.

Assets to Improve Coroutines

The solution to the coroutine issue mentioned above can be addressed by a free product and their pro version ot the product.

More Effective Coroutines

More Effective Coroutines is an improved implementation of Unity's coroutines that runs about twice as fast as Unity's coroutines do and has zero per-frame memory allocations. If you're interested in a performance comparison then take a look at the asset's right-most video

from their product page.
You can view this asset on the asset store by clicking here. This one is free.


This video provided by the author of this asset is extremely useful if you like videos and want a good rundown on coroutines.

More Effective Coroutines Pro


This is the same product as above, but with some better features.

MEC also adds additional functionality to coroutines, like a SlowUpdate loop (for updating the value of text boxes), and convenience methods that can call a delegate after a delay or continuously for some period of time.

This is the Pro version, which contains additional features and options that the free version lacks, but runs on the same core.

from the product page.
You can view this asset on the asset store by clicking here. This one costs $15.

Conclusion


This concludes another Unity tutorial. As always if you find this tutorial useful or worthy please up vote it so I know to continue to devote time and resources to making more resources. I have actually been using some SBD to purchase more assets so I can test other things and provide more tutorials and reviews.

Thank you for your time... Steem on!

Sort:  

These tutorials are awesome. Thank you!
I'm just curious, could you post a tutorial on how to export environments from Unity to Unreal 4?

What type of environments? I haven't attempted to do that before. I have only messed with Unreal 4 a little bit myself. Let me know what type of environments as not everything is the same across the board so if it is converting models from one to another I'd have to bug my son @theanubisrider as he is my 3D modeling expert. He's messed with Unreal 4 more than I have. I'm the coding, game design, and other things expert. He began modeling a few years ago and has quite the knack for it so I let him focus on that while I focus on other things. Let me know what you mean by environment and if I can help you I will.

Just exporting models would be great, but if you could do one one levels or landscape that would be even better. I know how to export those things from Blender but I'm curious if it's possible to do it from Unity to Unreal.

Landscape in unity is in it's own format natively. There are assets (I'd have to look to see if there are any free ones) that can convert the landscape to .obj. You should be able to do something with it then. As far as models they are typically in either .obj or .fbx format which I know Unreal can handle fine. I'll ask my son about that.

Awesome, good to know. I've been using Blender for some time now but it has problems exporting assets to Unreal but it can export to Unity no problem. The only reason a prefer Unreal is do to some legal aspects concerning the medium I wish to publish to. Thank you.

Coin Marketplace

STEEM 0.19
TRX 0.13
JST 0.029
BTC 60880.32
ETH 3371.93
USDT 1.00
SBD 2.52