# Object Pooling

The **Projectile Pool Manager** `prefab` should be brought into your scene.

<figure><img src="/files/9SnS04Kz4tkZCJip5zgU" alt=""><figcaption><p>You can turn on the Debug Logs option to see messages from the Projectile Pool Manager</p></figcaption></figure>

This system maintains a `ConcurrentDictionary<GameObject, Queue<GameObject>>` which holds all of the pooled Projectiles, as well as a `ConcurrentDictionary<string, Queue<GameObject>>` which holds other GameObjects returned to the pool.

## Putting Objects Into the Pool

[**Behaviors**](/magic-pig-games/projectile-factory/projectile-factory-documentation/behaviors.md) will automatically attempt to use the pool unless the [**Projectile**](/magic-pig-games/projectile-factory/projectile-factory-documentation/projectile.md) has this feature toggled off.

### `DestroyBehavior.cs`

Any `Behavior` created that is intended to destroy the `Projectile` should inherit from `DestroyBehavior`.  This has a built in method that will either put the object back into the pool, or destroy it, depending on the Projectile settings, called automatically when the `DoDestroy` event fires.

In the example below, the `AreaDamageOnDestroy` behavior overrides `DoDestroy()`, and causes some area at the position of the projectile, before calling `base.DoDestroy(projectile)`, which will trigger the default behavior -- putting the Projectile back into the pool.

```csharp
public override void DoDestroy(Projectile projectile)
{
     CauseDamageAtPosition(projectile, projectile.transform.position);
     base.DoDestroy(projectile); // This will put the projectile back into the pool
}

protected virtual void CauseDamageAtPosition(Projectile basicProjectile, Vector3 position)
{
     // Check the code for this example, removed here for brevity
}
```

### `ProjectilePowerDestroy.cs`

The [**Projectile Power Destroy**](/magic-pig-games/projectile-factory/projectile-factory-documentation/additional-scripts/destroy-or-pool-object.md) component can be added to objects that are spawned by Projectiles, such as impact particles. Many of the demo Projectiles make use of this pattern. The projectile will spawn an impact particle `prefab` whenever it collides. This means we probably want to use the **Object Pool** on those objects as well, since they'll be used repeatedly.

{% content-ref url="/pages/kqYiNeAZm23Wlz6UTRnw" %}
[Destroy or Pool Object](/magic-pig-games/projectile-factory/projectile-factory-documentation/additional-scripts/destroy-or-pool-object.md)
{% endcontent-ref %}

### Direct to the Pool

There are two methods to put Projectiles or GameObjects back into the pool. Both methods have an optional `float delay` which will delay the operation that actually puts the object back into the pool.

```csharp
public void PutBackProjectile(Projectile basicProjectile, float delay)
public void PutBackGameObject(GameObject objectToPutBack, float delay)
```

If you plan on making use of the **Object Pool** for `GameObjects` that are not `Projectiles`, then you can use the `PutBackGameObject()` method, which will work with any object you'd like to use.

{% hint style="warning" %}
The key for the `GameObject` pool is the name of the `GameObject`. The " *(Clone)*" that Unity automatically adds to object names will be removed from the name. This means that you should ensure your objects which you'll be putting into the pool, and taking back out, have unique names from other objects.
{% endhint %}

## Getting Objects From the Pool

### Spawn Behavior

The [**Spawn Behavior**](/magic-pig-games/projectile-factory/projectile-factory-documentation/spawn-behavior.md) will automatically attempt to pull objects from the pool before instantiating new instances, in the `SpawnProjectile()` method.

```csharp
// Grab the object from the pool, using the ProjectilePrefab (GameObject) as the key.
projectileObject = ProjectilePoolManager.instance.GetProjectile(ProjectilePrefab);

// If the pool returned null, we Instantiate instead
if (projectileObject == null)
     projectileObject = InstantiateNewProjectile(ProjectilePrefab, LaunchPosition(angleX, angleY), Quaternion.identity);
else
{
     // See the script for this code, removed for brevity
}
```

### Direct from the Pool

There are two methods to get Projectiles or `GameObjects` from the pool. The `GetProjectile()` method will first search for the Projectile based on the `objectToGet` provided. If it is not found, it will fallback to the `GetGameObject()` option.

```csharp
public GameObject GetProjectile(GameObject objectToGet)
public GameObject GetGameObject(GameObject objectToGet)
```

If you plan on making use of the **Object Pool** for `GameObjects` that are not `Projectiles`, then you can use the `GetGameObject()` method, which will work with any object you'd like to use.

## Debug Messages

The **Object Pool** has a built-in debug logger which you can turn on to see more details about objects going into and out of the pool. The frame number is included as well, which may help illustrate the order of things.

<figure><img src="/files/yZkW7p6CaePHkdtUaYMg" alt=""><figcaption><p>Lots of messages!</p></figcaption></figure>


---

# 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://infinitypbr.gitbook.io/magic-pig-games/projectile-factory/projectile-factory-documentation/object-pooling.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.
