I'm going to make this sort of lengthy.
This all started when we needed to spawn projectiles from multiple cannons from multiple players at or around the same time.
The instantiate function would cause our game to "chunk out" while this happened.
I was directed to an official Unity "Object Pooling" tutorial. The tutorial was for for a 2D space shooter.
The tutor said that this was only good for a limited amount of objects, and he was right.
The pool script he made was fine for a few dozen, maybe even 100, 2D game objects. For my 3D cannon projectiles the pool script started to make the game run even worse than the instantiate function would at around 25-50 game objects.
I got the just of what he was doing and proceed to write a much more efficient light weight ObjectStore script.
Here it is:
using UnityEngine;
using System.Collections;
public class ObjectStore : MonoBehaviour {
[SerializeField]
GameObject objectToStore;
[SerializeField]
int amountToStore;
GameObject cache;
int check;
int[] cacheRegistry;
// Use this for initialization
void Start () {
cacheRegistry = new int[amountToStore];
StoreObjects();
}
// Update is called once per frame
void Update () {
}
void StoreObjects ()
{
// initialze check to 0 so that we start checking at the begining of the cacheRegistry
check = 0;
// Loop throught he amount of objects we want to store, instantiate them, and register their InstanceID into cacheRegistry
for (int i = 0; i < amountToStore; i++)
{
cache = Instantiate(objectToStore);
// Ensure that all instantiated objects are not active in the hierarchy
if (cache.activeInHierarchy)
cache.SetActive(!true);
// Register cache's InstanceID into the cacheRegistry
cacheRegistry[i] = cache.GetInstanceID();
}
}
public GameObject CheckOut()
{
// Search through the cacheRegistry for inactive cache
for (int i = check; i < amountToStore;)
{
// Get cache from the cacheRegistry continuing from where we last checked
cache = (GameObject)UnityEditor.EditorUtility.InstanceIDToObject(cacheRegistry[check]);
// If inactive cache is found
if (cache.activeInHierarchy != true)
{
// Increase our check number by 1
check++;
// If we have reached the end of our checks go back to the starting check
if (check >= amountToStore)
{
check = 0;
}
return cache;
}
// If inactive cache is not found
// Increase our check number by 1
check++;
// If we have reached the end of our checks go back to the starting check
if (check >= amountToStore)
{
check = 0;
}
// because the check did not return cache, try again
i++;
}
// if the entire cacheRegistry does not have inactive cache
cache = null;
Debug.LogError("When attempting to check out " + objectToStore + " all of the cacheRegistry's checks had active cache. You must have inactive cache to CheckOut()");
return cache;
}
}
The issue of accessing an array, list, dictionary, whatever, is that you have to access it in it's ENTIRETY to access any single part.
That's what was causing the massive slow down, so I decided to store objects in their smallest possible form. An int. In this case unity already does this for you as an InstanceID (and that's why it stores them as an int).
This script copies the InstanceIDs to an array for only one certain type of GameObject that you specify in the editor.
This makes it even smaller than unity's internal InstanceID list (or what ever), and allows you to have multiple small ObjectStore scripts that will be accessed as quickly as possible.
It works great! Store 100,000 objects in a matter of seconds and access them virtually instantly.
The only problem is to actually take the stored int value of the InstaceID, and then type cast it to an object or GameObject that you can manipulate at run time.
The only way I have found to do this is:
UnityEditor.EditorUtility.InstanceIDToObject(int)
That's in the UnityEditor namespace, which means we can use it while playing in the editor, but when we go to build Unity will not allow us to use the namespace.
How do I override Unity to use the UnityEditor name space at build time?
Maybe there is another way to typecast InstanceID to object, game object etc. ?
Thanks!
↧