Пример #1
0
            private PoolableObj _NewPooledInstance(Vector3?position, Quaternion?rotation)
            {
                GameObject go;

                _isDuringInstantiate = true;

                if (position != null && rotation != null)
                {
                    go = (GameObject)GameObject.Instantiate(_prefabPoolObj.gameObject, (Vector3)position, (Quaternion)rotation);
                }
                else
                {
                    go = (GameObject)GameObject.Instantiate(_prefabPoolObj.gameObject);
                }

                _isDuringInstantiate = false;

                PoolableObj poolObj = go.GetComponent <PoolableObj>();

                poolObj._createdWithPoolController = true;
                poolObj._myPool = this;
                poolObj._isAvailableForPooling = false;
                poolObj._serialNumber          = ++_globalSerialNumber;
                poolObj._usageCount++;

                if (poolObj.DonotDestroyOnLoad)
                {
                    GameObject.DontDestroyOnLoad(go);
                }

                _pool.Add(poolObj);

                go.BroadcastMessage("OnPoolableInstanceAwake", SendMessageOptions.DontRequireReceiver);
                return(poolObj);
            }
Пример #2
0
        /// <summary>
        /// Sets the reference to a poolable object with the specified component.
        /// </summary>
        /// <param name="componentOfPoolableObject">The component of the poolable object.</param>
        /// <param name="allowNonePoolable">If set to false an error is output if the object does not have the <see cref="PoolableObj"/> component.</param>
        public void Set(T componentOfPoolableObject, bool allowNonePoolable)
#endif
        {
            if (!componentOfPoolableObject)
            {
                Reset();
                return;
            }
            _objComponent = (T)componentOfPoolableObject;
            _pooledObj    = _objComponent.GetComponent <PoolableObj>();
            if (!_pooledObj)
            {
                if (allowNonePoolable)
                {
                    _initialUsageCount = 0;
                }
                else
                {
                    Debug.LogError("Object for PoolableReference must be poolable");
                    return;
                }
            }
            else
            {
                _initialUsageCount = _pooledObj._usageCount;
            }
        }
Пример #3
0
        /// <summary>
        /// Preloads as many instances to the pool so that there are at least as many as
        /// specified in <see cref="PoolableObj.PreloadCount"/>.
        /// </summary>
        /// <param name="prefab">The prefab.</param>
        /// <remarks>
        /// Use ObjectPoolController.isDuringPreload to check if an object is preloaded in the <c>Awake()</c> function.
        /// If the pool already contains at least <see cref="PoolableObj.PreloadCount"/> objects, the function does nothing.
        /// </remarks>
        /// <seealso cref="PoolableObj.PreloadCount"/>
        static public void Preload(GameObject prefab) // adds as many instances to the prefab pool as specified in the PoolableObject
        {
            PoolableObj poolObj = prefab.GetComponent <PoolableObj>();

            if (poolObj == null)
            {
                Debug.LogWarning("Can not preload because prefab '" + prefab.name + "' is not poolable");
                return;
            }

            var pool = _GetPool(poolObj); // _preloadDone is set by _GetPool

            int delta = poolObj.PreloadCount - pool.GetObjectCount();

            if (delta <= 0)
            {
                return;
            }

            IsDuringPreload = true;

            try
            {
                for (int i = 0; i < delta; i++)
                {
                    pool.PreloadInstance();
                }
            }
            finally
            {
                IsDuringPreload = false;
            }

            //Debug.Log( "preloaded: " + prefab.name + " " + poolObj.preloadCount + " times" );
        }
Пример #4
0
            internal void _SetAvailable(PoolableObj poolObj, bool b)
            {
                poolObj._isAvailableForPooling = b;

                var objTransform = poolObj.transform;

                if (b)
                {
                    if (poolObj.SendAwakeStartOnDestroyMessage)
                    {
                        poolObj._destroyMessageFromPoolController = true;
                    }

                    objTransform.parent = null; // object could still be parented, so detach

                    _RecursivelySetInactiveAndSendMessages(poolObj.gameObject, poolObj, false);

                    objTransform.parent = poolObj._myPool.poolParentDummy; // attach to dummy Parent

                    //poolObj.gameObject.name = "pooled:" + poolObj._myPool._prefabPoolObj.name;
                }
                else
                {
                    objTransform.parent = null; // detach from poolParentDummy
                    _SetActiveAndSendMessages(poolObj.gameObject, poolObj);

                    //poolObj.gameObject.name = poolObj._myPool._prefabPoolObj.name;
                }
            }
Пример #5
0
            internal PoolableObj PreloadInstance()
            {
                _ValidatePooledObjectDataContainer();

                PoolableObj poolObj = _NewPooledInstance(null, null);

                poolObj._wasPreloaded = true;

                _SetAvailable(poolObj, true);

                return(poolObj);
            }
Пример #6
0
        static internal ObjectPool _GetPool(PoolableObj prefabPoolComponent)
        {
            ObjectPool pool;

            GameObject prefab = prefabPoolComponent.gameObject;

            if (!_pools.TryGetValue(prefab, out pool))
            {
                pool = new ObjectPool(prefab);
                _pools.Add(prefab, pool);
            }

            return(pool);
        }
Пример #7
0
            private void _RecursivelySetInactiveAndSendMessages(GameObject obj, PoolableObj parentPoolObj, bool recursiveCall)
            {
                // Create a local copy of all of the children before we potentially modify it
                // by removing a child PoolableObject by making a call to _SetAvailable()

                var objTransform = obj.transform;

                Transform[] children = new Transform[objTransform.childCount];

                for (int i = 0; i < objTransform.childCount; i++)
                {
                    children[i] = objTransform.GetChild(i);
                }

                //now recursively do the same for all children
                for (int i = 0; i < children.Length; i++)
                {
                    Transform child = children[i];

                    var poolableChild = child.gameObject.GetComponent <PoolableObj>();

                    if (poolableChild && poolableChild._myPool != null) //if child is poolable itself it has to be detached and moved to the pool
                    {
                        _SetAvailable(poolableChild, true);
                    }
                    else
                    {
                        _RecursivelySetInactiveAndSendMessages(child.gameObject, parentPoolObj, true);
                    }
                }

                if (parentPoolObj.SendAwakeStartOnDestroyMessage)
                {
                    obj.SendMessage("OnDestroy", null, SendMessageOptions.DontRequireReceiver);
                }

                if (parentPoolObj.SendPoolableActivateDeactivateMessages)
                {
                    obj.SendMessage("OnPoolableObjectDeactivated", null, SendMessageOptions.DontRequireReceiver);
                }

#if UNITY_3_x
#else
                if (!recursiveCall)
#endif
                {
                    _SetActive(obj, false);
                }
            }
Пример #8
0
        private static void _BroadcastMessageToAllChildren(GameObject go, string message)
        {
            Transform[] children = new Transform[go.transform.childCount]; // save child array, as it may change

            for (int i = 0; i < go.transform.childCount; i++)
            {
                children[i] = go.transform.GetChild(i);
            }

            //now recursively do the same for all children
            for (int i = 0; i < children.Length; i++)
            {
                if (children[i].GetComponent <PoolableObj>() == null) // if child object is PoolableObject then don't broadcast
                {
                    PoolableObj._BroadcastMessageToGameObject(children[i].gameObject, message);
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Gets the reference to the script component, or <c>null</c> if the object was
        /// already destroyed or moved to the pool.
        /// </summary>
        /// <returns>
        /// The reference to <c>T</c> or null
        /// </returns>
        public T Get()
        {
            if (!_objComponent)
            {
                return(null);
            }

            if (_pooledObj) // could be set to a none-poolable object
            {
                if (_pooledObj._usageCount != _initialUsageCount || _pooledObj._isAvailableForPooling)
                {
                    _objComponent = null;
                    _pooledObj    = null;
                    return(null);
                }
            }
            return((T)_objComponent);
        }
Пример #10
0
            private void _SetActiveAndSendMessages(GameObject obj, PoolableObj parentPoolObj)
            {
                _SetActive(obj, true);

                if (parentPoolObj.SendAwakeStartOnDestroyMessage)
                {
                    obj.BroadcastMessage("Awake", null, SendMessageOptions.DontRequireReceiver);

                    if (_GetActive(obj)
                        &&                                    // Awake could deactivate object
                        parentPoolObj._wasStartCalledByUnity) // for preloaded objects Unity will call Start
                    {
                        obj.BroadcastMessage("Start", null, SendMessageOptions.DontRequireReceiver);
                    }
                }

                if (parentPoolObj.SendPoolableActivateDeactivateMessages)
                {
                    obj.BroadcastMessage("OnPoolableObjectActivated", null, SendMessageOptions.DontRequireReceiver);
                }
            }
Пример #11
0
        static public GameObject Instantiate(GameObject prefab)
        {
            PoolableObj prefabPool = prefab.GetComponent <PoolableObj>();

            if (prefabPool == null)
            {
                //Debug.LogWarning( "Object " + prefab.name + " not poolable " );
                return((GameObject)GameObject.Instantiate(prefab)); // prefab not pooled, instantiate normally
            }

            GameObject go = _GetPool(prefabPool).GetPooledInstance(null, null);

            if (go)
            {
                return(go);
            }
            else // pool is full
            {
                return(InstantiateWithoutPool(prefab));
            }
        }
Пример #12
0
        static public void DestroyImmediate(GameObject obj)
        {
            PoolableObj poolObj = obj.GetComponent <PoolableObj>();

            if (poolObj == null)
            {
                _DetachChildrenAndDestroyImmediate(obj.transform); // child objects may be poolable
                GameObject.DestroyImmediate(obj);                  // prefab not pooled, destroy normally
                return;
            }
            if (poolObj._myPool != null)
            {
                poolObj._myPool._SetAvailable(poolObj, true);
            }
            else
            {
                if (!poolObj._createdWithPoolController)
                {
                    Debug.LogWarning("Poolable object " + obj.name + " not created with ObjectPoolController");
                }
                GameObject.DestroyImmediate(obj); // prefab not pooled, destroy normally
            }
        }
Пример #13
0
        static public GameObject InstantiateWithoutPool(GameObject prefab, Vector3 position, Quaternion quaternion)
        {
            GameObject go;

            _isDuringInstantiate = true;
            go = (GameObject)GameObject.Instantiate(prefab, position, quaternion); // prefab not pooled, instantiate normally
            _isDuringInstantiate = false;

            PoolableObj pool = go.GetComponent <PoolableObj>();

            if (pool)
            {
                if (pool.DonotDestroyOnLoad)
                {
                    GameObject.DontDestroyOnLoad(go);
                }

                pool._createdWithPoolController = true; // so no warning is displayed if object gets ObjectPoolCOntroller.Destroy()-ed before the component actually gets removed
                Component.Destroy(pool);
            }

            return(go);
        }
Пример #14
0
        static public GameObject Instantiate(GameObject prefab, Vector3 position, Quaternion quaternion)
        {
            PoolableObj prefabPool = prefab.GetComponent <PoolableObj>();

            if (prefabPool == null)
            {
                // no warning displayed by design because this allows to decide later if the object will be poolable or not
                // Debug.LogWarning( "Object " + prefab.name + " not poolable ");
                return((GameObject)GameObject.Instantiate(prefab, position, quaternion)); // prefab not pooled, instantiate normally
            }

            GameObject go = _GetPool(prefabPool).GetPooledInstance(position, quaternion);

            if (go)
            {
                return(go);
            }
            else // pool is full
            {
                //Debug.LogWarning( "Pool Full" );
                return(InstantiateWithoutPool(prefab, position, quaternion));
            }
        }
Пример #15
0
 /// <summary>
 /// Resets the reference to <c>null</c>.
 /// </summary>
 public void Reset()
 {
     _pooledObj         = null;
     _objComponent      = null;
     _initialUsageCount = 0;
 }
Пример #16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PoolableReference&lt;T&gt;"/> class from
 /// a given <see cref="PoolableReference&lt;T&gt;"/>.
 /// </summary>
 /// <param name="poolableReference">The poolable reference.</param>
 public PoolableReference(PoolableReference <T> poolableReference)
 {
     _objComponent      = poolableReference._objComponent;
     _pooledObj         = poolableReference._pooledObj;
     _initialUsageCount = poolableReference._initialUsageCount;
 }
Пример #17
0
 internal void Remove(PoolableObj poolObj)
 {
     _pool.Remove(poolObj);
 }
Пример #18
0
 public ObjectPool(GameObject prefab)
 {
     _prefabPoolObj = prefab.GetComponent <PoolableObj>();
 }