Reducing the number of enabled objects by disabling objects whenever possible

Optimization principal 1: Minimize the number of active and enabled objects in a scene.

Sometimes, we may not want to completely remove an object, but we can identify times when a scripted component of an object can be safely disabled. If a MonoBehaviour script is disabled, then Unity no longer needs to send the object messages, such as Update()and FixedUpdate(), for each frame.

For example, if a Non-Player Character (NPC) should only demonstrate some behavior when the player can see that character, then we only need to be executing the behavior logic when the NPC is visible—the rest of the time, we can safely disable the scripted component.

Unity provides the very useful events OnBecameInvisible() and OnBecameVisible(), which inform an object when it moves out of and into the visible area for one or more cameras in the scene.

This recipe illustrates the following rule of thumb: if an object has no reason to be doing actions when it cannot be seen, then we should disable that object while it cannot be seen.

Reducing the number of enabled objects by disabling objects whenever possible

Getting ready

For this recipe, we have prepared a package named unity4_assets_handyman_goodDirt containing the 3rdPersonController handyman and Terrain material goodDirt. The package is in the 1362_11_07 folder.

How to do it...

To disable objects to reduce computer processing workload requirements, follow these steps:

  1. Create a new Unity project, importing the provided Unity package unity4_assets_handyman_goodDirt.
  2. Create a new Terrain (size 20 x 20, located at -10, 0, -10) and texture-paint it with GoodDirt (which you'll find in the Standard Assets folder from your import of the Terrain Assets package).
  3. Add a 3rdPersonController at (0, 1, 0).
  4. Create a new Cube just in front of your 3rdPersonController (so it is visible in the Game panel when you start running the game).
  5. Add the following C# script class DisableWhenNotVisible to your Cube:
    using UnityEngine;
    using System.Collections;
    
    public class DisableWhenNotVisible : MonoBehaviour {
      private GameObject player;
    
      void Start(){
        player = GameObject.FindGameObjectWithTag("Player");
      }
    
      void OnBecameVisible() {
        enabled = true;
        print ("cube became visible again");
      }
    
      void OnBecameInvisible() {
        enabled = false;
        print ("cube became invisible");
      }
    
      void Update(){
        //do something, so we know when this script is NOT doing something!
        float d = Vector3.Distance( transform.position, player.transform.position);
        print(Time.time + ": distance from player to cube = " + d);
      }
    }

How it works...

When visible, the scripted DisableWhenNotVisible component of Cube recalculates and displays the distance from itself to the 3rdPersonController object's transform, via the variable player in the Update() method for each frame. However, when this object receives the message OnBecameInvisible(), the object sets its enabled property to false. This results in Unity no longer sending Update()messages to the GameObject, so the distance calculation in Update() is no longer performed; thus, reducing the game's processing workload. Upon receiving the message OnBecameVisible(), the enabled property is set back to true, and the object will then receive Update() messages for each frame. Note that you can see the scripted component become disabled by seeing the blue tick in its Inspector checkbox disappear if you have the Cube selected in the Hierarchy when running the game.

How it works...

The preceding screenshot shows our Console text output, logging how the user must have turned away from the cube at 6.9 seconds after starting the game (and so the cube was no longer visible); then, at 9.4 seconds, the user turned so that they could see the cube again, causing it to be re-enabled.

There's more...

Some details you don't want to miss:

Note – viewable in Scene panel still counts as visible!

Note that even if the Game panel is not showing (rendering) an object, if the object is visible in a Scene panel, then it will still be considered visible. Therefore, it is recommended that you hide/close the Scene panel when testing this recipe, otherwise it may be that the object does only becomes non-visible when the game stops running.

Another common case – only enable after OnTrigger()

Another common situation is that we only want a scripted component to be active if the player's character is nearby (within some minimum distance). In these situations, a sphere collider (with Is Trigger checked) can be set up on the object to be disabled/enabled (continuing our example, this would be on our Cube), and the scripted component can be enabled only when the player's character enters that sphere. This can be implemented by replacing the OnBecameInvisible() and OnBecameVisible() methods with the OnTriggerEnter() and OnTriggerExit() methods as follows:

void OnTriggerEnter(Collider hitObjectCollider) {
  if (hitObjectCollider.CompareTag("Player")){
    print ("cube close to Player again");
    enabled = true;
  }
}

void OnTriggerExit(Collider hitObjectCollider) {
  if (hitObjectCollider.CompareTag("Player")){
    print ("cube away from Player");
    enabled = false;
  }
}

The following screenshot illustrates a large sphere collider having been created around the cube, with its Trigger enabled:

Another common case – only enable after OnTrigger()

Many computer games (such as Half Life) use environmental design such as corridors to optimize memory usage by loading and unloading different parts of the environment. For example, when a player hits a corridor trigger, environment objects load and unload. See the following for more information about such techniques:

See also

Refer to the following recipes in this chapter for more information:

  • Reducing the number of objects by destroying objects at a death time
  • Reducing the number of active objects by making objects inactive whenever possible
..................Content has been hidden....................

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