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); }
/// <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; } }
/// <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" ); }
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; } }
internal PoolableObj PreloadInstance() { _ValidatePooledObjectDataContainer(); PoolableObj poolObj = _NewPooledInstance(null, null); poolObj._wasPreloaded = true; _SetAvailable(poolObj, true); return(poolObj); }
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); }
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); } }
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); } } }
/// <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); }
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); } }
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)); } }
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 } }
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); }
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)); } }
/// <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(PoolableObj poolObj) { _pool.Remove(poolObj); }
public ObjectPool(GameObject prefab) { _prefabPoolObj = prefab.GetComponent <PoolableObj>(); }