An editor extension to add 100 randomly located copies of a prefab with one menu click

Sometimes we want to create "lots" of pickups, randomly in our scene. Rather than doing this by hand, it is possible to add a custom menu and item to the Unity editor, which, when selected, will execute a script. In this recipe, we create a menu item that calls a script to create 100 randomly positioned star pickup prefabs in the Scene.

An editor extension to add 100 randomly located copies of a prefab with one menu click

Getting ready

This recipe assumes you are starting with the project Simple2Dgame_SpaceGirl setup from the first recipe in this chapter.

How to do it...

To create an editor extension to add 100 randomly located copies of a prefab with one menu click, follow these steps:

  1. Start with a new copy of mini-game Simple2Dgame_SpaceGirl.
  2. In the Project panel, create a new folder named Prefabs. Inside this new folder, create a new empty prefab named prefab_star. Populate this prefab by dragging GameObject star from the Hierarchy panel over prefab_star in the Project panel. The prefab should now turn blue and have a copy of all of GameObject star's properties and components.
  3. Delete GameObject star from the Hierarchy.
  4. In the Project panel, create a new folder named Editor. Inside this new folder, create a new C# script class named MyGreatGameEditor, with the following code:
    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    using System;
    public class MyGreatGameEditor : MonoBehaviour {
      const float X_MAX = 10f;
      const float Y_MAX = 10f;
    
      static GameObject starPrefab;
    
      [MenuItem("My-Great-Game/Make 100 stars")]
      static void PlacePrefabs(){
        string assetPath = "Assets/Prefabs/prefab_star.prefab";
        starPrefab = (GameObject)AssetDatabase.LoadMainAssetAtPath(assetPath);
    
        int total = 100;
        for(int i = 0; i < total; i++){
          CreateRandomInstance();
        }
      }
    
      static void CreateRandomInstance(){
        float x = UnityEngine.Random.Range(-X_MAX, X_MAX);
        float y = UnityEngine.Random.Range(-Y_MAX, Y_MAX);
        float z = 0;
        Vector3 randomPosition = new Vector3(x,y,z);
    
        Instantiate(starPrefab, randomPosition, Quaternion.identity);
      }
    }
  5. After 20 to 30 seconds, depending on the speed of your computer, you should now see a new menu appear, My Great Game, with a single menu item, Make 100 stars. Chose this menu item and, as if by magic, you should now see 100 new prefab_star(Clone) GameObjects appear in the scene!
    How to do it...

How it works...

The core aim of this recipe is to add a new menu, containing a single menu item that will execute the action we desire. C# attribute [MenuItem("<menuName>/<menuItemName>")] declares the menu name and the menu item name, and Unity will execute the static method that follows in the code listing, each time the menu item is selected by the user.

In this recipe, the [MenuItem("My-Great-Game/Make 100 stars")] statement declares the menu name as My-Great-Game and the menu item as Make 100 stars. The method immediately following this attribute is the PlacePrefabs() method. When this method is executed, it makes the starPrefab variable become a reference to the prefab found via the Assets/Prefabs/prefab_star.prefab path. Then, a for loop is executed 100 times, each time calling the CreateRandomInstance() method.

The CreateRandomInstance() method creates a Vector3 randomPosition variable, making use of X_MAX and Y_MAX constants. The Instantiate(...) built-in method is then used to create a new GameObject in the scene, making a clone of the prefab and locating it at the position defined by randomPosition.

There's more...

Some details you don't want to miss:

Child each new GameObject to a single parent, to avoid filling up the Hierarchy with 100s of new objects

Rather than having hundreds of new object clones fill up our Hierarchy panel, a good way to keep things tidy is to have an empty "parent" GameObject and child a collection of related GameObjects to it. Let's have a GameObject in the Hierarchy named Star-container and child all the new stars to this object.

Child each new GameObject to a single parent, to avoid filling up the Hierarchy with 100s of new objects

We need a variable that will be a reference to our container object, starContainerGO. We also need a new method, CreateStarContainerGO(), which will find a reference to GameObject star-container, if such an object already exists it is deleted, and then the method will create a new empty GameObject and give it this name. Add the following variable and method to our script class:

static GameObject starContainerGO;

static void CreateStarContainerGO() {
  string containerName = "Star-container";
  starContainerGO = GameObject.Find(containerName);
  if (null != starContainerGO) 
    DestroyImmediate(starContainerGO);
  starContainerGO = new GameObject(containerName);
}

Before we create the prefab clones, we need to first ensure we have created our star container GameObject. So we need to call our new method as the first thing we do when the PlacePrefabs() method is executed, so add a statement to call this method at the beginning of the PlacePrefabs() method:

static void PlacePrefabs(){
  CreateStarContainerGO();

  // rest of method as before ...
}

Now we need to modify the CreateRandomInstance() method so that it gets a reference to the new GameObject it has just created and can then child this new object to our star-container GameObject variable starContainerGO. Modify the CreateRandomInstance() method so that it looks as follows:

static void CreateRandomInstance() {
  float x = UnityEngine.Random.Range(-X_MAX, X_MAX);
  float y = UnityEngine.Random.Range(-Y_MAX, Y_MAX);
  float z = 0;
  Vector3 randomPosition = new Vector3(x,y,z);

  GameObject newStarGO = (GameObject)Instantiate(starPrefab, randomPosition, Quaternion.identity);
  newStarGO.transform.parent = starContainerGO.transform;
}
..................Content has been hidden....................

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