Getting InstanceID of the Gameobject from Pool

Anyone know how I can reference an InstanceID of a pooled gameobject?
I want the OnTrigger collider to pick and deactivate the specific clone from the pool instead of a random clone.
Right now when I collide with the clone, it’s deactivating a random clone from the pool, which I get, because I referenced the prefab from my spawner script and not my poolmanager.

Hope that made sense
The prefab script :

public void OnTriggerEnter(Collider player)
    {
       
        if (player.gameObject.tag == "Player" && mspawner.prefab != null)
        {
            value = Random.Range(100, 1000);
            money.addMoney(value);
            pool.ReuseObject(mspawner.prefab, pool.RandomSpawnpoint(), Quaternion.identity);
        }
       
    }

The Pool Manager script where I want to get the “int poolKey = prefab.GetInstanceID();” reference :

public void ReuseObject(GameObject prefab, Vector3 position, Quaternion rotation)
    {
        int poolKey = prefab.GetInstanceID();
        if (poolDictionary.ContainsKey(poolKey))
        {
            ObjectInstance objectToReuse = poolDictionary[poolKey].Dequeue();
            poolDictionary[poolKey].Enqueue(objectToReuse);
            objectToReuse.Reuse(position, rotation);
        }
    }

And my spawner script, if it helps:

public GameObject prefab;
    public int prefabCount;
    PoolManager pool;

    void Start()
    {
        pool = PoolManager.Instance;
        pool.GetSpawnPoints();
        pool.CreatePool(prefab, prefabCount);
        for (int i = 0; i < prefabCount; i++)
        {
            pool.ReuseObject(prefab, pool.RandomSpawnpoint(), Quaternion.identity);
        }
    }

I’m a bit confused about what your goal here is and how the object pooling is relevant.

In your OnTriggerEnter there are two GameObjects involved:

this.gameObject and player.gameObject.

Is there any reason you can’t just call this.gameObject.GetInstanceID() in OnTriggerEnter?

Hi thanks for taking a look and sorry for the confusion.

The PoolManager script is attached to the parent gameobject
The Mspawner script is attached to a child gameobject which holds all the random spawn location gameobjects and where I declare my prefab to be spawned.
The OnTriggerEnter is attached to the prefab.

My logic for the Ontrigger is if it’s the player that’s colliding with the gameobject then increase the money and then Enqueue the gameobject back to the pool.

How would I go about coding “this.gameObject.GetInstanceID()” in the OnTriggerEnter?

Thanks

Can’t you use exactly that?
this.gameObject.GetInstanceID()
That will give you the GameObject’s instance id and based on your other code you can use that directly as the key for your object pool.

I tried a similar approach where I made a variable for the prefab before posting but couldn’t get it to work. That’s why I was trying to reference it back to the MSpawner script where I declare my prefab to be spawned.

Do I put that code inside “pool.ReuseObject(this.gameobject.GetInstanceID(), pool.RandomSpawnpoint(), Quaternion.identity);” like that?

I get an error that the OnTrigger script does not contain a definition for gameobject.

The “O” needs to be capitalized.

this.gameObject

Oops sorry, should’ve fixed that. But still get an error “cannot convert from int to Unity.GameObject”

Then just use the gameObject directly?

I don’t really know how your pooling framework works so I’m kind of just guessing here. I’m a bit confused by some of your code above because it seems like you’re throwing the prefabs themselves into the pool? Normally you would be instantiating copies of the prefab and put the copies into the object pool, not the prefabs themselves. But I don’t know what’s happening in your “ReuseObject”
method for example.

Tried that already. I’ll post the whole script below. Should’ve done that from the start sorry.
Hope that makes more sense.

Pool Manager script

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PoolManager : MonoBehaviour
{
    Dictionary<int, Queue<ObjectInstance>> poolDictionary = new Dictionary<int, Queue<ObjectInstance>>();
    static PoolManager _instance;
    public List<Transform> spawnPoints = new List<Transform>();
    public static PoolManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<PoolManager>();
            }
            return _instance;
        }
    }
    public void CreatePool(GameObject prefab, int poolSize)
    {
        int poolKey = prefab.GetInstanceID();
        if (!poolDictionary.ContainsKey(poolKey))
        {
            poolDictionary.Add(poolKey, new Queue<ObjectInstance>());
            GameObject poolHolder = new GameObject(prefab.name + " pool");
            poolHolder.transform.parent = transform;
           
            for (int i = 0; i < poolSize; i++)
            {
                ObjectInstance newObject = new ObjectInstance(Instantiate(prefab) as GameObject);
                poolDictionary[poolKey].Enqueue(newObject);
                newObject.SetParent(poolHolder.transform);
            }
        }
    }
    public void ReuseObject(GameObject prefab, Vector3 position, Quaternion rotation)
    {
        int poolKey = prefab.GetInstanceID();
        if (poolDictionary.ContainsKey(poolKey))
        {
            ObjectInstance objectToReuse = poolDictionary[poolKey].Dequeue();
            poolDictionary[poolKey].Enqueue(objectToReuse);
            objectToReuse.Reuse(position, rotation);
        }
    }
    public class ObjectInstance
    {
        GameObject gameObject;
        Transform transform;
        bool hasPoolObjectComponent;
        PoolObject poolObjectScript;
        public ObjectInstance(GameObject objectInstance)
        {
            gameObject = objectInstance;
            transform = gameObject.transform;
            gameObject.SetActive(false);
            if (gameObject.GetComponent<PoolObject>())
            {
                hasPoolObjectComponent = true;
                poolObjectScript = gameObject.GetComponent<PoolObject>();
            }
        }

        public void Reuse(Vector3 position, Quaternion rotation)
        {
            if (hasPoolObjectComponent)
            {
                poolObjectScript.OnObjectReuse();
            }

            gameObject.SetActive(true);
            transform.position = position;
            transform.rotation = rotation;

            if (hasPoolObjectComponent)
            {
                poolObjectScript.OnObjectReuse();
            }
        }

        public void SetParent(Transform parent)
        {
            transform.parent = parent;
        }
    }

    //public method for getting a random spawnpoint
    public Vector3 RandomSpawnpoint()
    {
        int randomSP = Random.Range(0, (spawnPoints.Count));
        Vector3 randomSpawnPoint = spawnPoints[randomSP].transform.position;
        return randomSpawnPoint;
    }

    public void GetSpawnPoints()
    {
        //List using standard library and look through nested children
        Transform[] spList = transform.GetComponentsInChildren<Transform>();
        for (int i = 0; i < spList.Length; i++)
        {
            if (spList[i].tag == "TestSpawnPoints")
            {
                //add tagged gameobject to the list
                spawnPoints.Add(spList[i]);
            }
        }
    }

}

MSpawner script

using System.Collections.Generic;
using UnityEngine;

public class MSpawner : MonoBehaviour
{
    public static MSpawner Instance;
    private void Awake()
    {
        Instance = this;
    }

    public GameObject prefab;
    public int prefabCount;
    PoolManager pool;

    void Start()
    {
        pool = PoolManager.Instance;
        pool.GetSpawnPoints();
        pool.CreatePool(prefab, prefabCount);
        for (int i = 0; i < prefabCount; i++)
        {
            pool.ReuseObject(prefab, pool.RandomSpawnpoint(), Quaternion.identity);
        }
    }

}

SmallMoneyPickup = prefab

using UnityEditor;
using UnityEngine;

public class SmallMoneyPickup : PoolObject
{
   
    private int value;
    public MoneyManager money;
    PoolManager pool;
    MSpawner mspawner;

    public void Start()
    {
        pool = PoolManager.Instance;
        mspawner = FindObjectOfType<MSpawner>();
        money = FindObjectOfType<MoneyManager>();
    }

    public void OnTriggerEnter(Collider player)
    {
       
        if (player.gameObject.tag == "Player" && mspawner.prefab != null)
        {
            //int get = mspawner.prefab.GetInstanceID();
            value = Random.Range(100, 1000);
            money.addMoney(value);
            pool.ReuseObject(mspawner.prefab, pool.RandomSpawnpoint(), Quaternion.identity);
        }
       
    }

So if you just want to deactivate, why are you calling ReuseObject? Why not just deactivate it?

        if (player.gameObject.tag == "Player" && mspawner.prefab != null)
        {
            //int get = mspawner.prefab.GetInstanceID();
            value = Random.Range(100, 1000);
            money.addMoney(value);
            gameObject.SetActive(false);
        }

Ok, I get what you’re saying, and yes I’ve tried this way before. The prefab stays deactivated.

My main goal is to get all the money prefabs to spawn at Start, then reactivate that specific gameobject at a different location after colliding with the player. My logic might not be right then.

Should I leave it deactivated then and find another way to reactivate the prefab?

If you want to reactivate another one right away when money is picked up you can just do what you were doing before after deactivating:

        if (player.gameObject.tag == "Player" && mspawner.prefab != null)
        {
            //int get = mspawner.prefab.GetInstanceID();
            value = Random.Range(100, 1000);
            money.addMoney(value);
            gameObject.SetActive(false);
            pool.ReuseObject(mspawner.prefab, pool.RandomSpawnpoint(), Quaternion.identity);
        }
1 Like

Just tried it. Somehow it deactivates each gameobject (I have 4 activated at start) until the last one then reactivates only 1. lol

Edit : I think I know what the issue is. If the player collides with two gameobjects at the same time, the 2nd gameobject gets deactivated and never reactivates. I now need to find a way to make sure the gameobjects doesn’t stack together on the same location. Thanks for your help!

1 Like