Using Coroutines

Tutorial

·

intermediate

·

+10XP

·

20 mins

·

(126)

Unity Technologies

Using Coroutines

In this workflow, we’ll explore three instances of using Coroutines. Coroutines are methods that run independent from and simultaneous with the main thread.

Languages available:

1. Working with Coroutines

In this tutorial, we’ll explore three instances of using Coroutines. Coroutines are methods that run independently of and simultaneous with the main thread. This independence allows the Coroutine to run across frames, making it easy to perform large tasks that would otherwise bring a project to a halt. Another benefit is that the Coroutine retains flow control, allowing for easy looping and/or conditional behavior.


Coroutines are always of return type IEnumerator. When a Coroutine is finished, it needs to yield control. This can be for a set length of time until the end of the frame is reached, any other condition, or no condition (as seen in the data processing example).


2. Data Processing

Coroutines are extremely useful for processing data when time requirements exceed a single frame. This could be due to any combination of storage media, connection speed in the case of online retrieval, amount or complexity of data, or any number of factors. In a video game, this data could be an inventory of all in-game items, what the player owns, what the player has equipped, the player’s current stats, or overall progress in the game. In a non-game project, it could be information on the components of a physics simulation.


Let’s examine code used in actual production to load game inventory data. This data is loaded when the game starts. Because we need to be able to access this data across multiple Scenes, and because we’ll need more time than the first Scene uses, we’ve set the GameObject to DontDestroyOnLoad in the Awake() method (not shown). Because PlayerPrefs is unencrypted, we’re using the add-on ZPlayerPrefs, which adds a layer of encryption to secure stored data.


[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

In this project, Passive is the class used to contain both weapons and passive upgrades; passives is an array of all Passives in the game. The Boolean passiveOwnedEquippedSetup is used to track whether we’ve finished loading (or creating, the first time the game is run) the data. We set it to false at the beginning to prevent anything that requires this data from activating before it’s available.


Once we’ve processed each Passive, we yield control (with no condition in this case, so we use yield return null) so that we can move on in the loop. After all Passives have been processed, we set passiveOwnedEquippedSetup to true and yield once more to exit the Coroutine.


3. Looping Behavior

One common example of looping behavior using a Coroutine is displaying a sequence of images, from vacation photos to digital ads, each for a fixed amount of time, restarting the sequence after the final image appears. The entire script, Slideshow.cs, follows. Create a raw image in your Scene, and attach this script either to it or to a new empty GameObject. In the Slideshow Inspector, drag the raw image into the slot labeled Display, and drop your images onto Slides.


[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Where our first Coroutine ran only once, Display loops. Because this Coroutine never ends, we only need to yield while we’re waiting to display the next image.


In our final example, we’ll build a platform that moves between two endpoints. This code works in 2D or 3D. Attach the following script, MovingPlatform.cs, to your platform and assign your start and end points before entering Play Mode. These start and end points can be new empty GameObjects or existing elements in your Scene.


[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

In Start(), we move the platform to the start point and set its destination to the end point. If the user has specified how long the journey should take, the platform’s speed is calculated to meet this requirement. Otherwise, a default speed is used. Finally we set our direction to forward and start the Coroutine.


As in our slideshow example, while(true) causes our code to loop indefinitely. An inner while loop tracks the platform’s distance from the destination. Once the destination has been reached, the platform pauses for a specified amount of time, changes direction, and sets a new destination, restarting the inner loop.


4. Conclusion

This has been just a sampling of the utility of Coroutines. Though these examples are fairly universal, you’re sure to find many more uses that are unique to your project.


Complete this tutorial