public void PoolGameObjectInfoListAdd() { foreach (var item in Resources.LoadAll <GameObject>("Prefabs")) { PoolGameObjectInfo newPoolInfo = new PoolGameObjectInfo(); newPoolInfo.poolGameobjectName = item.gameObject.name; newPoolInfo.poolPrefab = item; poolsList.Add(newPoolInfo); } }
/// <summary> /// Pools the object specified. Will not be pooled if there is no prefab of that type. /// </summary> /// <param name='obj'> /// Object to be pooled. /// </param> /// <returns> /// true if object could be pooled, false otherwise /// </returns> public bool Pool(GameObject obj, string objectKind = null, Transform poolParent = null) { if (obj == null) { return(false); } if (objectKind == null) { objectKind = obj.name; } PoolGameObjectInfo poolObjectKind = poolObjectList.Find(element => objectKind.Equals(element.id)); if (poolObjectKind != null) { bool objectPrefabListExists = pooledObjects.ContainsKey(poolObjectKind.id); // Create a new list for this kind of pooled objects (only known ones) if (!objectPrefabListExists) { pooledObjects.Add(poolObjectKind.id, new List <GameObject>(1)); } } // reset its velocity if not kinematic if (obj.GetComponent <Rigidbody>() && !obj.GetComponent <Rigidbody>().isKinematic) { obj.GetComponent <Rigidbody>().velocity = Vector3.zero; obj.GetComponent <Rigidbody>().angularVelocity = Vector3.zero; } // Never pool object in the editor, while not playing if (!Application.isPlaying) { DestroyImmediate(obj); } else { if (poolObjectKind == null || pooledObjects[poolObjectKind.id].Count > poolObjectKind.maxCount) { // Destroy an object that can't be pooled Destroy(obj); } else { // Deactivate the object, reset its position and scale obj.SetActive(false); // - set default parent or requested one obj.transform.SetParent(poolObjectKind.defaultParent); obj.transform.localPosition = Vector3.zero; obj.transform.localScale = Vector3.one; // Put the object in the object pool pooledObjects[poolObjectKind.id].Insert(0, obj); } } return(true); }
GameObject InstantiateObject(PoolGameObjectInfo poolObject) { Transform parent = poolObject.defaultParent != null ? poolObject.defaultParent : transform; GameObject newObj = Instantiate(poolObject.prefab, parent) as GameObject; // Attach to object pool by default if (newObj.transform.parent == null) { newObj.transform.SetParent(transform); } newObj.transform.localScale = Vector3.one; newObj.name = poolObject.id; return(newObj); }
} // initPoolSystem public void InitPoolGameObject(GameObject prefab, string namePrefab, int initialAmount, bool replace = false) { PoolGameObjectInfo poolInfo; if (_elements.TryGetValue(namePrefab, out poolInfo)) { if (prefab == poolInfo.prefab) { Debug.LogWarning("The pool was already created"); if (poolInfo.elements.Count < initialAmount) { GameObject go; for (int i = initialAmount - poolInfo.elements.Count - 1; i >= 0; --i) { go = GameObject.Instantiate <GameObject>(prefab); go.transform.SetParent(_container); go.transform.localScale = Vector3.one; poolInfo.elements.Add(go); } } } else { if (!replace) { Debug.LogWarning("Name prefab used for another prefab. Choose another namePrefab to save or set replace = true for replaceOld prefab"); } else { _elements.Remove(namePrefab); } } return; } poolInfo = new PoolGameObjectInfo(); List <GameObject> list = new List <GameObject>(); GameObject tempGo; for (int i = initialAmount - 1; i >= 0; --i) { tempGo = GameObject.Instantiate <GameObject>(prefab); tempGo.transform.SetParent(_container); list.Add(tempGo); } poolInfo.prefab = prefab; poolInfo.elements = list; _elements.Add(namePrefab, poolInfo); } // InitPoolGameObject
public void ReleaseGO(String res, GameObject go, PoolObjectType type) { //获取缓存节点,设置为不可见位置 if (objectsPool == null) { objectsPool = new GameObject("ObjectPool"); objectsPool.AddComponent <UIPanel>(); objectsPool.transform.localPosition = new Vector3(0, -5000, 0); } if (null == res || null == go) { //Debug.LogError(res + "Release go error"); return; } //拖尾处理 if (go.tag == "nopool") { GameObject.Destroy(go); return; } PoolInfo poolInfo = null; //没有创建 if (!mPoolDic.TryGetValue(res, out poolInfo)) { poolInfo = new PoolInfo(); mPoolDic.Add(res, poolInfo); } PoolGameObjectInfo poolGameObjInfo = new PoolGameObjectInfo(); poolGameObjInfo.type = type; poolGameObjInfo.name = res; //无效缓存物体 DisablePoolGameObject(go, poolGameObjInfo); //保存缓存GameObject,会传入相同的go, 有隐患 //poolInfo.mQueue.Add(go,poolGameObjInfo); poolInfo.mQueue[go] = poolGameObjInfo; }
/// <summary> /// Create a new type of pooled object /// </summary> /// <param name="name"></param> /// <param name="prefab"></param> /// <param name="tag"></param> /// <param name="bufferCount"></param> /// <param name="maxCount"></param> /// <param name="defaultParent"></param> public void NewPoolKind(string name, GameObject prefab, string tag = "Default", int bufferCount = 1, int maxCount = -1, Transform defaultParent = null) { PoolGameObjectInfo poolObjectKind = poolObjectList.Find(element => name.Equals(element.id)); if (poolObjectKind == null) { poolObjectKind = new PoolGameObjectInfo(); poolObjectKind.bufferCount = bufferCount; poolObjectKind.defaultParent.SetParent(defaultParent); poolObjectKind.id = name; poolObjectKind.maxCount = maxCount; poolObjectKind.prefab = prefab; poolObjectList.Add(poolObjectKind); GameObject newObj = Instantiate(poolObjectKind.prefab) as GameObject; newObj.name = poolObjectKind.id; Pool(newObj, poolObjectKind.id, poolObjectKind.defaultParent); } }
/// <summary> /// Gets a new object for the name type provided. If no object type exists or if onlypooled is true and there is no objects of that type in the pool /// then null will be returned. /// </summary> /// <returns> /// The object for type. /// </returns> /// <param name='objectType'> /// Object type. /// </param> /// <param name='onlyPooled'> /// If true, it will only return an object if there is one currently pooled. /// </param> public GameObject GetFromPool(string objectName, bool onlyPooled, bool activate) { PoolGameObjectInfo poolObject = poolObjectList.Find(element => objectName.StartsWith(element.id)); bool objectPrefabExists = (poolObject != null); #if UNITY_EDITOR // Don't get from pool while in editor and not playing if (!Application.isPlaying) { return(InstantiateObject(poolObject)); } #endif if (objectPrefabExists) { // Get from the pool if there's one left if (pooledObjects.ContainsKey(objectName) && pooledObjects[objectName].Count > 0) { if (pooledObjects[objectName][0] != null) { GameObject pooledObject = pooledObjects[objectName][0]; pooledObjects[objectName].RemoveAt(0); pooledObject.SetActive(activate); pooledObject.transform.SetParent(poolObject.defaultParent); return(pooledObject); } return(InstantiateObject(poolObject)); } else if (!onlyPooled) { if (poolObject != null) { return(InstantiateObject(poolObject)); } return(null); } } // If we have gotten here either there was no object of the specified type or none were left in the pool with onlyPooled set to true return(null); }
//取得可用对象 private bool TryGetObject(PoolInfo poolInfo, out KeyValuePair <GameObject, PoolGameObjectInfo> objPair) { if (poolInfo.mQueue.Count > 0) { foreach (KeyValuePair <GameObject, PoolGameObjectInfo> pair in poolInfo.mQueue) { GameObject go = pair.Key; PoolGameObjectInfo info = pair.Value; if (info.mCanUse) { objPair = pair; return(true); } } } objPair = new KeyValuePair <GameObject, PoolGameObjectInfo>(); return(false); }
//获取缓存物体 public GameObject GetGO(String res) { //有效性检查 if (null == res) { return(null); } //查找对应pool,如果没有缓存 PoolInfo poolInfo = null; KeyValuePair <GameObject, PoolGameObjectInfo> pair; if (!mPoolDic.TryGetValue(res, out poolInfo) || !TryGetObject(poolInfo, out pair)) { //新创建 //Debug.LogError("res = " + res); ResourceUnit unit = ResourcesManager.Instance.loadImmediate(res, ResourceType.PREFAB); if (unit.Asset == null) { Debug.Log("can not find the resource" + res); } return(GameObject.Instantiate(unit.Asset) as GameObject); } //出队列数据 GameObject go = pair.Key; PoolGameObjectInfo info = pair.Value; poolInfo.mQueue.Remove(go); //使有效 EnablePoolGameObject(go, info); //返回缓存Gameobjec return(go); }
public void OnUpdate() { //每隔0.1更新一次 mTotalTime += Time.deltaTime; if (mTotalTime <= 0.1f) { return; } else { mTotalTime = 0; } float deltaTime = Time.deltaTime; //遍历数据 foreach (PoolInfo poolInfo in mPoolDic.Values) { //死亡列表 mDestoryPoolGameObjects.Clear(); foreach (KeyValuePair <GameObject, PoolGameObjectInfo> pair in poolInfo.mQueue) { GameObject obj = pair.Key; PoolGameObjectInfo info = pair.Value; info.mCacheTime += deltaTime; float mAllCachTime = mCachTime; //POT_UITip,缓存3600秒 if (info.type == PoolObjectType.POT_UITip) { mAllCachTime = 3600; } //缓存时间到 if (info.mCacheTime >= mAllCachTime) { mDestoryPoolGameObjects.Add(obj); } //拖尾重置计时 if (!info.mCanUse) { info.mResetTime += deltaTime; if (info.mResetTime > 1.0f) { info.mResetTime = .0f; info.mCanUse = true; obj.SetActive(false); } } } //移除 for (int k = 0; k < mDestoryPoolGameObjects.Count; k++) { GameObject obj = mDestoryPoolGameObjects[k]; //obj.transform.parent = null; GameObject.DestroyImmediate(obj); poolInfo.mQueue.Remove(obj); } } }
//设置缓存物体有效 public void DisablePoolGameObject(GameObject go, PoolGameObjectInfo info) { //特效Disable if (info.type == PoolObjectType.POT_Effect) { ParticleSystem[] particles = go.GetComponentsInChildren <ParticleSystem>(true); foreach (ParticleSystem part in particles) { part.Clear(); } //解绑到poolGameobject节点 go.transform.parent = objectsPool.transform; //拖尾处理 if (go.tag == "trail") { info.mCanUse = false; TrailRenderer[] trailRenders = go.GetComponentsInChildren <TrailRenderer>(); foreach (TrailRenderer trail in trailRenders) { info.mTrailTimes[trail] = trail.time; trail.time = -10; } XffectComponent[] xffects = go.GetComponentsInChildren <XffectComponent>(true); foreach (XffectComponent xffect in xffects) { xffect.DoFinish(); xffect.gameObject.SetActive(false); } MeshRenderer[] renders = go.GetComponentsInChildren <MeshRenderer>(true); foreach (MeshRenderer render in renders) { render.gameObject.SetActive(false); } foreach (ParticleSystem part in particles) { part.gameObject.SetActive(false); } } else { info.mCanUse = true; go.SetActive(false); } } else if (info.type == PoolObjectType.POT_MiniMap) { //go.transform.parent = objectsPool.transform; go.SetActive(false); } else if (info.type == PoolObjectType.POT_Entity) { //解绑到poolGameobject节点 go.transform.parent = objectsPool.transform; go.SetActive(false); } else if (info.type == PoolObjectType.POT_UITip) { //解绑到poolGameobject节点 go.transform.parent = objectsPool.transform; go.SetActive(false); } else if (info.type == PoolObjectType.POT_XueTiao) { go.transform.parent = objectsPool.transform; XueTiaoUI xt = go.GetComponent <XueTiaoUI>(); xt.SetVisible(false); } }
//设置缓存物体无效 public void EnablePoolGameObject(GameObject go, PoolGameObjectInfo info) { //特效Enable if (info.type == PoolObjectType.POT_Effect) { go.SetActive(true); //prewarm的情况需要模拟一个周期运行 if (go.tag == "prewarm") { go.transform.localPosition = new Vector3(0, -5000, 0); ParticleSystem[] particles = go.GetComponentsInChildren <ParticleSystem>(true); foreach (ParticleSystem part in particles) { if (part.gameObject.tag == "prewarm" && part.loop) { part.Simulate(part.duration); part.Play(); } } go.transform.localPosition = new Vector3(0, 0, 0); } //拖尾处理 if (go.tag == "trail") { ParticleSystem[] particles = go.GetComponentsInChildren <ParticleSystem>(true); foreach (ParticleSystem part in particles) { part.gameObject.SetActive(true); } XffectComponent[] xffects = go.GetComponentsInChildren <XffectComponent>(true); foreach (XffectComponent xffect in xffects) { xffect.Active(); } TrailRenderer[] trailRenders = go.GetComponentsInChildren <TrailRenderer>(true); foreach (TrailRenderer trail in trailRenders) { if (info.mTrailTimes.ContainsKey(trail)) { trail.time = info.mTrailTimes[trail]; } } MeshRenderer[] renders = go.GetComponentsInChildren <MeshRenderer>(true); foreach (MeshRenderer render in renders) { render.gameObject.SetActive(true); } } go.transform.parent = null; } else if (info.type == PoolObjectType.POT_MiniMap) { go.SetActive(true); go.transform.parent = null; } else if (info.type == PoolObjectType.POT_Entity) { go.SetActive(true); go.transform.parent = null; } else if (info.type == PoolObjectType.POT_UITip) { go.SetActive(true); go.transform.parent = null; } else if (info.type == PoolObjectType.POT_XueTiao) { //do nothing } info.mCacheTime = 0.0f; }