- Home /
The question is answered, right answer was accepted
Why Do My Obstacles Do This In My Object Pooler?
I am almost done with my Object Pooling System for my PickAxe GameObject, but I have this one problem I need help with.
What I am trying to figure out is why all of my spawning restarts whenever the first PickAxe hits the wall? How do I make to where the PickAxe just goes back into the "pooler" whenever it hits the wall?
I took two screenshots and I'll post my code below too. The first one is just before the first Pickaxe that was spawned hits the wall, and the second screenshot is right after that same PickAxe hit the wall.
Some of my code below:
This script spawns my PickAxes. I am 99% sure my problem is where I am calling my Event function in my CoRoutine. Am I right?
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Obstacle4 // Pick Axe Obstacle
{
public float SpawnWait; // Time in seconds between next wave of obstacle 4.
public float StartGameWait; // Time in seconds between when the game starts and when the fourth obstacle start spawning.
public float WaveSpawnWait; // Time in seconds between waves when the next wave of obstacle 4 will spawn.
}
public class SpawnPickAxe : MonoBehaviour
{
public GameObject pickAxePrefab;
public Obstacle4 obstacle4_;
void Start ()
{
PickAxePoolManager.instance.CreatePool (pickAxePrefab, 15); //CreatePool is a method in PickAxePoolManager
StartCoroutine (PickAxeSpawner ());
}
IEnumerator PickAxeSpawner ()
{
yield return new WaitForSeconds (obstacle4_.StartGameWait);
while (true)
{
for (int i = 0; i < 5; i++)
{
Vector3 newSpawnPosition = new Vector3 (Random.Range(-10.0f, 10.0f), 1.2f, 30.0f);
Quaternion newSpawnRotation = Quaternion.Euler (0.0f, -90.0f, 0.0f);
PickAxePoolManager.instance.ReuseObject (pickAxePrefab, newSpawnPosition, newSpawnRotation); //ReuseObject is also a method in PickAxePoolManager
//Instantiate (obstacle4.pickAxe, spawnPosition, spawnRotation);
yield return new WaitForSeconds (obstacle4_.SpawnWait);
ResetByWall.instance.onTriggerEntered += delegate(GameObject obj)
{
PickAxePoolManager.instance.ReuseObject(pickAxePrefab, newSpawnPosition, newSpawnRotation);
};
}
yield return new WaitForSeconds (obstacle4_.WaveSpawnWait);
}
}
}
Below is my PoolManager Script. You might not even need to look at this script but I posted it anyways lol.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PickAxePoolManager : MonoBehaviour {
Dictionary<int,Queue<GameObject>> poolDictionary = new Dictionary<int,Queue<GameObject>>();
//NOTE:
//Singleton Pattern used from lines 12 to 25
static PickAxePoolManager _instance; // Reference to the Pool Manager script
public static PickAxePoolManager instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<PickAxePoolManager>(); //Find the instance in the Pool Manager script in the currently active scene
}
return _instance;
}
}
/// <summary>
/// Creates the pool.
/// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="poolSize">Pool size.</param>
public void CreatePool(GameObject prefab, int poolSize)
{
int poolKey = prefab.GetInstanceID (); // Unique integer for every GameObject
if (!poolDictionary.ContainsKey (poolKey)) //Make sure poolKey is not already in the Dictionary,
//if it's not then we can create the pool
{
poolDictionary.Add(poolKey, new Queue<GameObject>());
for (int i = 0; i < poolSize; i++) //Instantiate the prefabs as dictated by the "poolSize" integer
{
GameObject newObject = Instantiate (prefab) as GameObject; //Instantiate as a GameObject
newObject.SetActive(false); // Don't want it to be visible in the scene yet
poolDictionary [poolKey].Enqueue(newObject); // Add it to our Pool
}
}
}
/// <summary>
/// Reuses the object in our pool.
/// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="position">Position.</param>
/// <param name="rotation">Rotation.</param>
public void ReuseObject (GameObject prefab, Vector3 position, Quaternion rotation)
{
int poolKey = prefab.GetInstanceID (); // Get our pool key once again
if (poolDictionary.ContainsKey (poolKey)) // Quick check to make sure our pool dictionary contains the pool key
{
GameObject objectToReuse = poolDictionary[poolKey].Dequeue(); //Get the next object in the pool
poolDictionary[poolKey].Enqueue(objectToReuse); // Add the object back onto the end of the queue so it can be reused later
objectToReuse.SetActive(true); //Make sure the object was not disabled
objectToReuse.transform.position = position; // set position to applied values
objectToReuse.transform.rotation = rotation; // set rotation to applied values
}
}
}
And below is my "ResetByWall" script. This script is also important because it contains the public Event that allows me to detect a collision with whatever collides with my wall, and my wall is the trigger.
using System;
using UnityEngine;
using System.Collections;
public class ResetByWall : MonoBehaviour
{
//public bool collided;
//public GameObject pickAxePrefab;
//NOTE:
//Singleton Pattern from lines 12 to 25 //
// ************************************
static ResetByWall _instance; // Reference to the Reset By Wall script
public static ResetByWall instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<ResetByWall>(); //Find the instance in the Reset By Wall script in the currently active scene
}
return _instance;
}
}
public event Action <GameObject> onTriggerEntered;
void OnTriggerEnter(Collider other)
{
if (onTriggerEntered != null) {
onTriggerEntered (other.gameObject);
}
}
}
Answer by stephen_george98 · Jul 10, 2016 at 08:34 AM
I solved it. I decided to just use this in my ResetByWall script:
void OnTriggerEnter (Collider obstacle)
{
if (obstacle.gameObject.tag == "Pick Axe")
{
obstacle.gameObject.SetActive (false);
}
}