Coroutines allow us to write asynchronous code—we can ask a method to go off and calculate something, but the rest of the game can keep on running without having to wait for that calculation to end. Or we can call a coroutine method for each frame from Update()
and organize the method to complete part of a complex calculation each time it is called. When games start requiring complex computations, such as for artificial intelligence reasoning, it may not be possible to maintain acceptable game performance when trying to complete all calculations in a single frame; this is where coroutines can be an excellent solution.
This recipe illustrates how a complex calculation can be structured into several pieces, each to be completed one frame at a time.
An excellent description of coroutines (and other Unity topics) can be found on Ray Pendergraph's wikidot website at http://raypendergraph.wikidot.com/unity-developer-s-notes#toc6.
To spread computations over several frames, perform the following steps:
SegmentedCalculation.cs
in the Main Camera:// file: SegmentedCalculation.cs using UnityEngine; using System.Collections; public class SegmentedCalculation : MonoBehaviour { private const int ARRAY_SIZE = 50; private const int SEGMENT_SIZE = 10; private int[] randomNumbers; private void Awake(){ randomNumbers = new int[ARRAY_SIZE]; for(int i=0; i<ARRAY_SIZE; i++){ randomNumbers[i] = Random.Range(0, 1000); } StartCoroutine( FindMinMax() ); } private IEnumerator FindMinMax() { int min = 9999; int max = -1; for(int i=0; i<ARRAY_SIZE; i++){ if( i % SEGMENT_SIZE == 0){ print("frame: " + Time.frameCount + ", i:" + i + ", min:" + min + ", max:" + max); // suspend for 1 frame since we've completed another segment yield return null; } if( randomNumbers[i] > max){ max = randomNumbers[i]; } else if( randomNumbers[i] < min){ min = randomNumbers[i]; } } // disable this scripted component print("** completed - disabling scripted component"); enabled = false; } }
frame: 1, i:0, min:9999, max:-1 frame: 2, i:10, min:30, max:793 frame: 3, i:20, min:30, max:892 frame: 4, i:30, min:4, max:892 frame: 5, i:40, min:4, max:905 ** completed - disabling scripted component
An array called randomNumbers
of random integers is created in Awake()
. Then the FindMinMax()
method is started as a coroutine. The size of the array is defined by the ARRAY_SIZE
constant, and the number of elements to process each frame by SEGMENT_SIZE
.
The FindMinMax()
method
sets initial values for min
and max
and begins to loop through the array. If the current index is divisible by the SEGMENT_SIZE
(remainder 0), then we make the method display the current frame number and variable values, and suspend execution for one frame with a yield null
statement. For each loop, the value for the current array index is compared with min
and max
, and those values are updated if a new minimum or maximum has been found. When the loop is completed, the scripted component disables itself.
The following are some details you don't want to miss:
As well as seeing log texts in the Console panel, you can also access the Unity editor log text file as follows:
~/Library/Logs/Unity/Editor.log
C:UsersusernameAppDataLocalUnityEditorEditor.log
For more information about Unity logfiles, see the online manual at http://docs.unity3d.com/Documentation/Manual/LogFiles.html.
18.117.75.70