예제 #1
0
        /// <summary>
        /// Returns a pool that is appropriate for storing identical copies of an object.
        /// </summary>
        static TransformPool GetAssociatedPool(GameObject gameObject, int chunkSize, int maxPoolSize)
        {
            //first, we need to know the id we will be using for this object's pool
            //if there is no PoolId attached we know this wasn't created by this pooler.
            //In that case, treat is as a prefab. WARNING: If it isn't actually a prefab and we
            //destroy it later, this could cause some serious issues!
            PoolId p  = null;
            int    id = PoolIdValue(gameObject, out p);

            //now we need to see if we have a pool for it yet
            TransformPool pool = null;

            if (!Pools.TryGetValue(id, out pool))
            {
                //looks like we need to create a new pool for this type of object
                GameObject go = new GameObject("Pool: " + id + " (" + gameObject.name + ")");
                go.transform.SetParent(Instance.transform, false);
                pool             = go.AddComponent <TransformPool>();
                pool.PoolId      = id;
                Pools[id]        = pool;
                pool.ChunkSize   = chunkSize;
                pool.MaxPoolSize = maxPoolSize;
                pool.AllocTime   = AllocTime;

                //WARNING: This is a potential bug if we actually passed a live object and not a prefab!
                //If we destroy the live object, we can't properly use the pool associated with it!
                pool.Prefab = gameObject.transform;
            }

            return(pool);
        }
예제 #2
0
        /// <summary>
        /// Returns the object to this pool. If the pool is at
        /// capcity, the object will be destroyed instead.
        /// Objects relenquished this way should be considered
        /// destroyed for all intents and purposes and must never
        /// be accessed again without using the pool's 'obtain' method.
        /// </summary>
        /// <param name="thing"></param>
        public virtual void RelenquishObject(T thing, PoolId poolId = null)
        {
            _ActiveList.Remove(thing.gameObject);

            #if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                //TODO: check if slot or this pool is a prefab before destroying
                //NOTE: There is no built-in surefire way to determine prefab status
                //but rumor has it that the hideflags can be used to imply such a status
                GameObject.DestroyImmediate(thing.gameObject);
                return;
            }
            #endif


            #if UNITY_EDITOR
            if (TypeHelper.IsReferenceNull(transform) || transform.childCount >= MaxPoolSize)
            #else
            if (transform.childCount >= MaxPoolSize)
            #endif
            {
                //if we have enough in our pool, just destroy
                #if UNITY_EDITOR
                if (Application.isPlaying)
                {
                    GameObject.Destroy(thing.gameObject);
                }
                else
                {
                    GameObject.DestroyImmediate(thing.gameObject);
                }
                #else
                GameObject.Destroy(thing.gameObject);
                #endif
            }
            else
            {
                //send back to pool
                thing.gameObject.SetActive(false);
                //TODO: Confirm if this is still a bug in 5.6+
                //thing.transform.SetParent(null); //must do this due to bug in Unity involving prefabs
                thing.transform.SetParent(this.transform);

                //NOTE: not an entirely pure system anymore... but whatever
                if (poolId != null)
                {
                    poolId.InPool = true;
                }
                else
                {
                    poolId = thing.GetComponent <PoolId>();
                    if (poolId != null)
                    {
                        poolId.InPool = true;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Helper for retreiving the number used to identify
        /// to what pool an object should belong.
        /// </summary>
        /// <param name="gameObject"></param>
        /// <returns></returns>
        public static int PoolIdValue(GameObject gameObject, out PoolId pool)
        {
            int id;
            var poolId = gameObject.GetComponent <PoolId>();

            if (poolId != null)
            {
                id = poolId.Id;
            }
            else
            {
                id = gameObject.GetInstanceID();
            }
            pool = poolId;
            return(id);
        }
예제 #4
0
        /// <summary>
        /// Relenquishes an object to the internal pooling mechanism. For all intents
        /// and purposes, this should be treated the same as calling Destroy on the GameObject
        /// and it should no longer be accessed. If the internal pool is at maximum capacity
        /// the GameObject will be destroyed.
        ///
        /// Note that even if an object was not instantiated using a pool, it can still be
        /// relenquished to one, however, the pool it is placed in will not be the same one
        /// as any other copies that were instantiated using Summon().
        /// </summary>
        /// <param name="gameObject"></param>
        public static void RelenquishToPool(GameObject gameObject)
        {
            if (gameObject == null)
            {
                return;
            }

            //don't use pools during editmode, it f***s everything
            #if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                var prefabType = UnityEditor.PrefabUtility.GetPrefabType(gameObject);
                if (prefabType == UnityEditor.PrefabType.None ||
                    (int)prefabType >= (int)UnityEditor.PrefabType.PrefabInstance)
                {
                    DestroyImmediate(gameObject);
                }
                else
                {
                    Debug.LogWarning("Could not destroy prefab: " + gameObject.name);
                }
                return;
            }
            #endif

            if (MaxPoolSize < 1)
            {
                Destroy(gameObject);
                return;
            }

            //If we don't have a pool for this object's id
            //we know it didn't come from one. We just want
            //to destroy it like normal.
            PoolId p  = null;
            int    id = PoolIdValue(gameObject, out p);

            TransformPool pool = null;
            if (Pools.TryGetValue(id, out pool))
            {
                pool.RelenquishObject(gameObject.transform, p);
            }
            else
            {
                Destroy(gameObject);
            }
        }