- Home /
The question is answered, right answer was accepted
Organize Inspector Better?
As is shown in my screenshot above, at the start of my scene all of my PickAxe GameObjects are instantiated and they take up a bunch of space in my Inspector.
Is there any way for my to organize these better and have them as a child of another GameObject or have them under a tab? It's not completely necessary but It would look a lot better, considering I am about to have 3 more types of obstacles added into the scene also. I am not sure if this helps, but I'll post my completed ObjectPooler script below:
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 13 to 26
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 CreatePickAxePool(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 ReusePickAxe (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
}
}
}
Thank you! :)
Answer by Devastus · Jul 10, 2016 at 01:33 PM
You can parent a Transform into another, which you can do right after instantiation:
newObject.transform.parent = exampleObject.transform;
You may want to create a new, empty GameObject for the pooled objects before starting to instantiate them, which you could do when creating the pool itself.
In my game, I am not really "Instantiating" my obstacles, I am just activating and deactivating them. Does the same principle apply? Do you want to see of one of my ObstacleSpawning scripts, if that would help? Thank you! @Devastus
I wasn't necessarily very clear with what I meant there, sorry.
When you are creating the pool and instantiating it's objects at it's creation for the first time, you can make an empty GameObject to contain these objects to not clutter the Editor. You could do something like this inside your CreatePickAxePool():
GameObject pooledObjects = new GameObject();
pooledObjects.name = "Pooled Objects";
for (int i = 0; i < poolSize; i++) //Instantiate the prefabs as dictated by the "poolSize" integer
{
GameObject newObject = Instantiate(prefab) as GameObject;
newObject.transform.parent = pooledObjects.transform;
poolDictionary [pool$$anonymous$$ey].Enqueue(newObject);
}
You only have to do this once, and the objects will be found underneath the "Pooled Objects" GameObject. $$anonymous$$inda like an object tree.
In a little test game of $$anonymous$$e that included several different enemies controlled by a Central AI that could run over 300 entities, I pooled the enemies so that they wouldn't take enormous amount of resources with instantiation. It included an object tree for every different type of enemy. Here's a snippet of the creation code:
//Initialize and create the object pool
public void CreatePool()
{
objectPool = new GameObject[_poolLength];
int objectsLeft = _poolLength;
for (int i = 0; i < objects.Count; i++)
{
GameObject objectTree = new GameObject(objects[i].obj.name);
objectTree.transform.parent = this.transform;
objectTrees.Add(objectTree);
for (int x = 0; x < objects[i].amount; x++)
{
objectPool[_poolLength - objectsLeft] = Instantiate(objects[i].obj, transform.position, Quaternion.identity) as GameObject;
objectPool[_poolLength - objectsLeft].name = objects[i].obj.name;
objectPool[_poolLength - objectsLeft].transform.parent = objectTree.transform;
objectPool[_poolLength - objectsLeft].SetActive(false);
objectsLeft--;
}
}
}
Nothing fancy, but may give you some ideas. There's also some extra stuff with multiple arrays and lists that you don't really need in order to get several object trees happening, that's just something I was messing around with for other functionality.
Works perfect!! Thank you so much for your help! I accepted your answer and gave you as much reward points as I was allowed, lol. Have a great day! Thanks again :) @Devastus