# Simple Spawner

### Objects to Spawn - PickUp Prefabs

**PickUp Prefabs** to be Spawned in the MiniGame should have the following configuration:\
&#x20;[See PickUp PreFabs](/cs2335/project-1-simple-game/pickup_items.md)

* PickUp GameObjects should be a PreFab
* A SpriteRenderer Component
* At least 1 Collider2D component with IsTrigger set to true (can have additional nested Collider2D components if necessary)
* A PickUp script component, with the public attributes like: value, type set in the inspector.
* GameObject: Tag:  "Collectible" or "Hazard"
* Can have a Rigidbody2D if the spawned object will be moving
* Can have an Animator component if the object will be animated

  **Important:** The **PickUp** Prefabs must have **Tag** that corresponds to  Tags in OnTriggerEnter2D( ).

### Simple Spawner Logic

**Logic Overview:** \
&#x20;    Define variables that can be customized for each instance of a Spawner:

* Specify PickUp prefabs to spawn ( good, bad )
* Specify total number of prefabs to spawn (numToSpawn)
* Specify probability of bad prefabs to spawn. (chanceToSpawnBad)
* Constrain where objects will be spawned. (xRange, yRange)
* Determine time between spawning objects (pauseTime)
* Define boolean variable that can toggle: (stop, start) spawning

### **Spawner Methods, Helper Methods**&#x20;

#### **Start Spawning:**

* **`SpawnPrefab( )`**&#x20;
  * private method, executed in a loop in **`StartSpawning( )`**
  * spawns 1 prefab instance - with some probability of it being good / bad type
  * will only spawn a prefab if **`activeSpawning`** is true;
* **`StartSpawning ( )`**&#x20;
  * public method to be executed in MiniGameManager
  * For testing, we'll start with calling this in **`Start( )`** - we'll remove this code later
  * has a loop that invokes **`SpawnPrefab( )`** multiple times with delays

#### **Stop Spawning:**

* **`DestroyAllSpawnedObjects(  )`**  &#x20;
  * Creates Array of PickUps by Finding all items of type **`< PickUp >`** in the scene
* **`StopAllSpawning( )`**&#x20;
  * Cancels all Invoked **`SpawnPrefab( )`** methods
  * Sets **activeSpawning** to false;
  * Executes **DestroyAllSpawnedObjects( )**

### **Important Spawner GameObject Configuration Details:** &#x20;

When **initializing the Inspector** Panel for Spawner Component:\
1\.  **Delete all PickUp Prefab** gameObjects from **the Scene**\
2\.  **Select Original Prefab from Assets**:  GoodPrefab, BadPrefab (from the Assets tab) see image below<br>

![Select Prefab from Assets Tab, Not the Scene Tab](/files/-MHSJm-vdVFBHRfa6fJf)

![Select Prefab From Assets, Not from the Scene](/files/-MHSITQEUy2kb1xwAJ9g)

### Spawner.cs

* The code below creates a simple spawner.&#x20;
* Create a C# Script in your project Assets:  Spawner.&#x20;
* Double-click the script so that it opens in Visual Studio. &#x20;
* Add the code from below to the script.  &#x20;
* In Visual Studio, build to compile the script. &#x20;
* In Unity, Add the **Spawner.cs** component to an empty GameObject, Spawner in the scene.

```java
//Sept 17, 2020
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    [Header("Set in Inspector")]
    public GameObject goodPrefab, badPrefab;

    public bool activeSpawning = false;

    [SerializeField]
    int pauseTime = 2; //may need to customize for your game

    [SerializeField]
    int numToSpawn = 10; //customize as needed

    [SerializeField]
    float chanceToSpawnBad = 0.10f; //modify as needed

    [SerializeField]
    float xRangeLeft = -8.0f; //customize as needed

    [SerializeField]
    float xRangeRight = 8.0f; //customize as needed

    [SerializeField]
    float yRangeTop = -2.0f; //customize as needed

    [SerializeField]
    float yRangeBottom = -3.5f; //customize as needed

    // Start is called before the first frame update
    void Start()
    {
        activeSpawning = true; //remove this code later
        StartSpawning(); //remove this code later, move to MiniGameManager
    }


    ///Will be exectued in MiniGameManager when startButton clicked
    //MiniGameState is set to active
    public void StartSpawning()
    {
        Debug.Log("Start Spawning called");
        //Loop generates multiple delayed invocations of SpawnPrefab( ) method.
        for (int i = 0; i < numToSpawn; i++)
        {
            Invoke("SpawnPrefab", pauseTime * i * 2);  //Delays between SpawnPrefab( ) exection
        }
    }

    //Executed from the StartSpawning method
    //Many instances of this method will be invoked 
    void SpawnPrefab()
    {
        if (activeSpawning) //won't actually spawn anything unless this is true 
        {
            //Where to spawn based on transform of Spawner gameObject

            Vector3 position = transform.localPosition;
            position.x = Random.Range(xRangeLeft, xRangeRight);
            position.y = Random.Range(yRangeBottom, yRangeTop);

            float rand = Random.value;
            GameObject prefab; //temp variable 
            if (rand < chanceToSpawnBad)
            { //spawn bad prefab
                prefab = Instantiate(badPrefab, position, transform.rotation);
            }
            else  //instantiate good one
            {
                prefab = Instantiate(goodPrefab, position, transform.rotation);
            }
            prefab.transform.SetParent(this.transform); //all spawned objects will be children of the Spawner gameObject
        }
    }//end SpawnPrefab

    //This will be executed from MiniGameManager
    public void StopAllSpawning()
    {
        CancelInvoke("SpawnPrefab");  //cancels all SpawnPrefab( ) methods waiting to be executed
        activeSpawning = false;
        DestroySpawnedObjects();
    }

    //Exectued in StopAllSpawning
    private void DestroySpawnedObjects()
    {
        PickUp[] items = FindObjectsOfType<PickUp>();
        foreach (PickUp item in items)
        {
            Destroy(item.gameObject);
        }
    }

}// end class Spawner

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kdoore.gitbook.io/cs2335/project1-code/simple-spawner.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
