0
\$\begingroup\$

I'm trying to follow this tutorial about object pooling in Unity

I got to minute 17:22. But when I run the game I get this exception:

ArgumentException: An element with the same key already exists in the dictionary.

System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.Queue`1[UnityEngine.GameObject]].Add (System.String key, System.Collections.Generic.Queue`1 value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:404)
ObjectPooler.Start () (at Assets/Scripts/ObjectPooler.cs:31)

This script is attached to a new empty GameObject:

using System.Collections.Generic;
using UnityEngine;

public class ObjectPooler : MonoBehaviour
{
    [System.Serializable]
    public class Pool
    {
        public string tag;
        public GameObject prefab;
        public int size;
    }

    public List<Pool> pools;
    public Dictionary<string, Queue<GameObject>> poolDictionary;

    private void Start()
    {
        poolDictionary = new Dictionary<string, Queue<GameObject>>();

        foreach(Pool pool in pools)
        {
            Queue<GameObject> objectPool = new Queue<GameObject>();

            for (int i = 0; i < pool.size; i++)
            {
                GameObject obj = Instantiate(pool.prefab);
                obj.SetActive(false);
                objectPool.Enqueue(obj);

                poolDictionary.Add(pool.tag, objectPool);
            }
        }
    }
}

Like in the tutorial I'm making size of 1 of the Pools in the Inspector then giving as tag name: Cube then drag a cube prefab to the Prefab then set the size to 150.

But I'm getting this exception when running the game.

\$\endgroup\$
1
\$\begingroup\$

In the innermost loop of Start(), you're trying to add objectPool to the poolDictionary using pool.tag as the key. This innermost loop executes once for every slot in the pool, and pool.tag is the same for each invocation, thus the exception. It also doesn't seem to make that much sense, placed there.

It looks to me like what you want is to add objectPool to poolDictionary outside the for loop, and add each new game object to objectPool inside the for loop. Something like this:

foreach(Pool pool in pools) {
  Queue<GameObject> objectPool = new Queue<GameObject>();

  // Insert into poolDictionary here, not in the loop below.
  poolDictionary.Add(pool.tag, objectPool);

  for (int i = 0; i < pool.size; i++) {
    GameObject obj = Instantiate(pool.prefab);
    obj.SetActive(false);
    objectPool.Enqueue(obj);
  }
}

Provided every pool has a unique tag value, this should work the way you expect.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.