目录为:Assets/Scripts/Common/
文件为ObjectPool.cs
这个文件主要定义了一个对象池,可以参考一下.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
public enum PoolObjectType
{
POT_Effect,
POT_MiniMap,
POT_Entity,
POT_UITip,
POT_XueTiao,
}
public class PoolGameObjectInfo
{
public string name;
public float mCacheTime = 0.0f;
public PoolObjectType type;
public EffectLodLevel lodLevel;
#region //拖尾处理
public bool mCanUse = true;
public float mResetTime = .0f;
public Dictionary<TrailRenderer, float> mTrailTimes = new Dictionary<TrailRenderer, float>();
#endregion
}
public class PoolInfo
{
public Dictionary<GameObject, PoolGameObjectInfo> mQueue = new Dictionary<GameObject, PoolGameObjectInfo> ();
}
public class GameObjectPool: Singleton<GameObjectPool>
{
private Dictionary<String, PoolInfo> mPoolDic = new Dictionary<string, PoolInfo> ();
private GameObject objectsPool;
private float mCacheTime = 1800.0f;
private List<GameObject> mDestroyPoolGameObjects = new List<GameObject> ();
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> ();
}
public GameObject GetGO(String res)
{
if (null == res)
{
return null;
}
KeyValuePair<GameObject, PoolGameObjectInfo> pair;
if (!mPoolDic.TryGetValue(res, out PoolInfo) || !TryGetObject(PoolInfo, out pair))
{
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);
return go;
}
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)
{
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);
poolInfo.mQueue [go] = poolGameObjInfo;
}
public void EnablePoolGameObject(GameObject go, PoolGameObjectInfo info)
{
if (info.type == PoolObjectType.POT_Effect)
{
go.SetActive (true);
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)
{
}
info.mCacheTime = 0.0f;
}
public void DisablePoolGameObject(GameObject go, PoolGameObjectInfo info)
{
if (info.type == PoolObjectType.POT_Effect)
{
ParticleSystem[] particles = go.GetComponentsInChildren<ParticleSystem> (true);
foreach (ParticleSystem part in particles)
{
part.Clear ();
}
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.SetActive (false);
}
else if (info.type == PoolObjectType.POT_Entity)
{
go.transform.parent = objectsPool.transform;
go.SetActive (false);
}
else if (info.type == PoolObjectType.POT_UITip)
{
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 Clear()
{
mPoolDic.Clear ();
mDestroyPoolGameObjects.Clear ();
objectsPool = null;
}
float mTotalTime = 0;
public void OnUpdate()
{
mTotalTime += Time.deltaTime;
if (mTotalTime <= 0.1f)
{
return;
}
else
{
mTotalTime = 0;
}
float deltaTime = Time.deltaTime;
foreach(PoolInfo poolInfo in mPoolDic.Values)
{
mDestroyPoolGameObjects.Clear ();
foreach (KeyValuePair<GameObject, PoolGameObjectInfo> pair in poolInfo.mQueue)
{
GameObject obj = pair.Key;
PoolGameObjectInfo info = pair.Value;
info.mCacheTime += deltaTime;
float mAllCacheTime = mCacheTime;
if (info.type == PoolObjectType.POT_UITip)
{
mAllCacheTime = 3600.0f;
}
if (info.mCacheTime >= mAllCacheTime)
{
mDestroyPoolGameObjects.Add (obj);
}
if (!info.mCanUse)
{
info.mResetTime += deltaTime;
if (info.mResetTime > 1.0f)
{
info.mResetTime = 0.0f;
info.mCanUse = true;
obj.SetActive (false);
}
}
}
for (int k = 0; k < mDestroyPoolGameObjects.Count; k++)
{
GameObject obj = mDestroyPoolGameObjects [k];
GameObject.DestroyImmediate (obj);
poolInfo.mQueue.Remove (obj);
}
}
}
}