Spreading long computations over several frames with coroutines

Optimization principal 3: Call methods as few times as possible.

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.

Note that coroutines are not threads, but they are very handy in that each can progress each frame further. It also allows us to write code that does not have to wait for certain methods to complete before another can begin.

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.

Note

Note: An excellent description of coroutines (and other Unity topics) can be found on Ray Pendergraph's wikidot website http://raypendergraph.wikidot.com/unity-developer-s-notes#toc6.

How to do it...

To spread computations over several frames, follow these steps:

  1. Add the following script class SegmentedCalculation to the Main Camera:
    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 = int.MaxValue;
        int max = int.MinValue
    
        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;
      }
    }
  2. Run the game, and you'll see how the search for highest and lowest values in the array progresses in steps, avoiding undesirable delays between each new frame.
    How to do it...

How it works...

The randomNumbers array of random integers is created in Awake(). Then, the FindMinMax() method is started as a coroutine. The size of the array is defined by constant ARRAY_SIZE, 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 every 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.

There's more...

Some details you don't want to miss:

Retrieving the complete Unity log text files from your system

As well as seeing log texts in the Console panel, you can also access the Unity editor log text file as follows:

  • Mac:
    • ~/Library/Logs/Unity/Editor.log
    • And access through the standard Console app
  • Windows:
    • C:UsersusernameAppDataLocalUnityEditorEditor.log
  • Mobile devices (see the Unity documentation for accessing device log data)
    Retrieving the complete Unity log text files from your system

For more information about Unity logs files, see the online manual at http://docs.unity3d.com/Manual/LogFiles.html.

See also

Refer to the Executing methods regularly but independent of frame rate with coroutines recipe in this chapter for more information.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.24.60