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);
}
}
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?
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.
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);
}
}
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?
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!