// **************************************************************************************************/ // public functions // **************************************************************************************************/ /// <summary> /// Retrieves an instance of the specified prefab. Either returns a new instance or it claims an instance /// from the pool. /// </summary> /// <param name="prefab">The prefab to be instantiated.</param> /// <returns> /// An instance of the prefab. /// </returns> /// <remarks> /// Can be used on none-poolable objects as well. It is good practice to use <c>ObjectPoolController.Instantiate</c> /// whenever you may possibly make your prefab poolable in the future. /// </remarks> /// <seealso cref="Destroy(GameObject)"/> static public GameObject Instantiate(GameObject prefab, Transform parent = null) { PoolableObject prefabPool = prefab.GetComponent <PoolableObject>(); if (prefabPool == null) { //Debug.LogWarning( "Object " + prefab.name + " not poolable " ); return(( GameObject )_InstantiateGameObject(prefab, Vector3.zero, Quaternion.identity, parent)); // prefab not pooled, instantiate normally } GameObject go = _GetPool(prefabPool).GetPooledInstance(null, null, prefab.activeSelf, parent); return(go ?? InstantiateWithoutPool(prefab, parent)); }
private PoolableObject _NewPooledInstance(Vector3?position, Quaternion?rotation, bool createActive, bool addToPool) { _isDuringInstantiate = true; _prefab._SetActive(false); GameObject go = (GameObject)GameObject.Instantiate( _prefab, position ?? Vector3.zero, rotation ?? Quaternion.identity ); _prefab._SetActive(true); PoolableObject poolObj = go.GetComponent <PoolableObject>(); poolObj._pool = this; poolObj._serialNumber = ++_globalSerialNumber; poolObj.name += poolObj._serialNumber; if (poolObj.doNotDestroyOnLoad) { GameObject.DontDestroyOnLoad(poolParent); } _pool.Add(poolObj); if (addToPool) { poolObj._PutIntoPool(); } else { poolObj._usageCount++; if (createActive) { go.SetActive(true); if (poolObj.sendPoolableActivateDeactivateMessages) { CallMethodOnObject(poolObj.gameObject, "OnPoolableObjectActivated", true, true, poolObj.useReflectionInsteadOfMessages); } } } _isDuringInstantiate = false; return(poolObj); }
/// <summary> /// Retrieves an instance of the specified prefab. Either returns a new instance or it claims an instance /// from the pool. /// </summary> /// <param name="prefab">The prefab to be instantiated.</param> /// <param name="position">The position in world coordinates.</param> /// <param name="quaternion">The rotation quaternion.</param> /// <returns> /// An instance of the prefab. /// </returns> /// <remarks> /// Can be used on none-poolable objects as well. It is good practice to use <c>ObjectPoolController.Instantiate</c> /// whenever you may possibly make your prefab poolable in the future. /// </remarks> /// <seealso cref="Destroy(GameObject)"/> static public GameObject Instantiate(GameObject prefab, Vector3 position, Quaternion quaternion, Transform parent = null) { PoolableObject prefabPool = prefab.GetComponent <PoolableObject>(); 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 )_InstantiateGameObject(prefab, position, quaternion, parent)); // prefab not pooled, instantiate normally } GameObject go = _GetPool(prefabPool).GetPooledInstance(position, quaternion, prefab.activeSelf, parent); return(go ?? InstantiateWithoutPool(prefab, position, quaternion, parent)); }
static internal ObjectPool _GetPool(PoolableObject prefabPoolComponent) { ObjectPool pool; GameObject prefab = prefabPoolComponent.gameObject; var instanceID = prefab.GetInstanceID(); if (!_pools.TryGetValue(instanceID, out pool)) { pool = new ObjectPool(prefab); _pools.Add(instanceID, pool); } return(pool); }
/// <summary> /// Instantiates the specified prefab without using pooling. /// from the pool. /// </summary> /// <param name="prefab">The prefab to be instantiated.</param> /// <param name="position">The position in world coordinates.</param> /// <param name="quaternion">The rotation quaternion.</param> /// <returns> /// An instance of the prefab. /// </returns> /// <remarks> /// If the prefab is poolable, the <see cref="PoolableObject"/> component will be removed. /// This way no warning is generated that a poolable object was created without pooling. /// </remarks> static public GameObject InstantiateWithoutPool(GameObject prefab, Vector3 position, Quaternion quaternion, Transform parent = null) { _isDuringInstantiate = true; GameObject go = _InstantiateGameObject(prefab, position, quaternion, parent); // prefab not pooled, instantiate normally _isDuringInstantiate = false; PoolableObject pool = go.GetComponent <PoolableObject>(); if (pool != null) { pool._wasInstantiatedByObjectPoolController = true; Component.Destroy(pool); } return(go); }
internal GameObject GetPooledInstance(Vector3?position, Quaternion?rotation, bool activateObject, Transform parent = null) { _ValidatePooledObjectDataContainer(); PoolableObject instance = null; for (int i = 0; i < _pool.Count; i++) { var pooledElement = _pool.ElementAt(i); if (pooledElement == null) // can happen e.g. at scene loads, so we need to clean up { _pool.RemoveAt(i--); continue; } if (pooledElement._isInPool) { instance = pooledElement; var transform = pooledElement.transform; transform.position = (position != null) ? ( Vector3 )position : _poolableObjectComponent.transform.position; transform.rotation = (rotation != null) ? ( Quaternion )rotation : _poolableObjectComponent.transform.rotation; transform.localScale = _poolableObjectComponent.transform.localScale; break; } } if (instance == null && _pool.Count < _poolableObjectComponent.maxPoolSize) //create and return new element { instance = _NewPooledInstance(position, rotation, activateObject, false); instance.transform.SetParent(parent, true); //instance.transform.parent = parent; return(instance.gameObject); } if (instance != null) { instance.TakeFromPool(parent, activateObject); return(instance.gameObject); } else { return(null); } }
/// <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._isInPool) { _objComponent = null; _pooledObj = null; return(null); } } return((T)_objComponent); }
/// <summary> /// Preloads as many instances to the pool so that there are at least as many as /// specified in <see cref="PoolableObject.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="PoolableObject.preloadCount"/> objects, the function does nothing. /// </remarks> /// <seealso cref="PoolableObject.preloadCount"/> static public void Preload(GameObject prefab) // adds as many instances to the prefab pool as specified in the PoolableObject { PoolableObject poolObj = prefab.GetComponent <PoolableObject>(); if (poolObj == null) { Debug.LogWarning("Can not preload because prefab '" + prefab.name + "' is not poolable"); return; } var pool = _GetPool(poolObj); //check how much Objects need to be preloaded int delta = poolObj.preloadCount - pool.GetObjectCount(); if (delta <= 0) { return; } isDuringPreload = true; bool preloadActive = prefab.activeSelf; try { for (int i = 0; i < delta; i++) { //dont use prefab.activeSelf because this may change inside Preloadinstance. use the cached value "preloadActive" pool.PreloadInstance(preloadActive); } } finally { isDuringPreload = false; } //Debug.Log( "preloaded: " + prefab.name + " " + poolObj.preloadCount + " times" ); }
/// <summary> /// Instantiates the specified prefab without using pooling. /// from the pool. /// </summary> /// <param name="prefab">The prefab to be instantiated.</param> /// <param name="position">The position in world coordinates.</param> /// <param name="quaternion">The rotation quaternion.</param> /// <returns> /// An instance of the prefab. /// </returns> /// <remarks> /// If the prefab is poolable, the <see cref="PoolableObject"/> component will be removed. /// This way no warning is generated that a poolable object was created without pooling. /// </remarks> static public GameObject InstantiateWithoutPool(GameObject prefab, Vector3 position, Quaternion quaternion, Transform parent = null) { _isDuringInstantiate = true; GameObject go = _InstantiateGameObject(prefab, position, quaternion, parent); // prefab not pooled, instantiate normally _isDuringInstantiate = false; PoolableObject pool = go.GetComponent <PoolableObject>(); if (pool != null) { pool._instantiatedByObjectPoolController = true; // allows disabled game objects with deferred Awake to check if they were instantiated by ObjectPoolController if (pool.doNotDestroyOnLoad) { GameObject.DontDestroyOnLoad(go); } Component.Destroy(pool); } return(go); }
/// <summary> /// Resets the reference to <c>null</c>. /// </summary> public void Reset() { _pooledObj = null; _objComponent = null; _initialUsageCount = 0; }
/// <summary> /// Initializes a new instance of the <see cref="PoolableReference<T>"/> class from /// a given <see cref="PoolableReference<T>"/>. /// </summary> /// <param name="poolableReference">The poolable reference.</param> public PoolableReference(PoolableReference <T> poolableReference) { _objComponent = poolableReference._objComponent; _pooledObj = poolableReference._pooledObj; _initialUsageCount = poolableReference._initialUsageCount; }
internal void Remove(PoolableObject poolObj) { _pool.Remove(poolObj); }
public ObjectPool(GameObject prefab) { this._prefab = prefab; this._poolableObjectComponent = prefab.GetComponent <PoolableObject>(); }