容器(用于存放缓存的对象)
游戏对象池 池=容器=【字典】 列表?
放元素=游戏对象{技能A,技能B,特效,.....}
专门针对 游戏场景中的游戏对象 使用池技术
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
/// <summary>
/// 游戏对象池:
/// </summary>
public class GameObjectPool : MonoSingleton<GameObjectPool>{
//单例模式对象池
private GameObjectPool(){}
//1 创建池:
private Dictionary<string, List<GameObject>> cache =
new Dictionary<string, List<GameObject>>();
//2 创建使用池的元素【游戏对象】一个对象并使用对象:
//池中有从池中返回;池中没有加载,放入池中再返回
public GameObject CreateObject(string key,GameObject go,
Vector3 positon, Quaternion quaternion)
{
//1)查找池中有无可用游戏对象
GameObject temoGo = FindUsable(key);
//2)池中有从池中返回;
if (temoGo != null)
{ temoGo.transform.position = positon;
temoGo.transform.rotation = quaternion;
temoGo.SetActive(true);//表示当前这个游戏对象在使用中
}
else//3)池中没有加载,放入池中再返回
{
temoGo = Instantiate(go, positon, quaternion) as GameObject;
//放入池中
Add(key, temoGo);
}
//作为池物体的子物体
temoGo.transform.parent = this.transform;
return temoGo;//
}
private GameObject FindUsable(string key)
{
if (cache.ContainsKey(key))
{
//找列表 中找出 未激活【未活动】的游戏物体
return cache[key].Find(p => !p.activeSelf);
}
return null;
}
private void Add(string key,GameObject go)
{
//先检查池中是否 有需要的key,没有,需要向创建key和对应的列表。
if (!cache.ContainsKey(key))
{
cache.Add(key, new List<GameObject>());
}
//把游戏对象添加到 池中
cache[key].Add(go);
}
//3 释放资源:从池中删除对象!
//3.1释放部分:按Key释放
public void Clear(string key)
{
if (cache.ContainsKey(key))
{
//释放场景中 的游戏物体
for (int i = 0; i < cache[key].Count; i++)
{ Destroy(cache[key][i]); }
//移除了对象的地址
cache.Remove(key);
}
}
//3.2释放全部 循环调用Clear(string key)
public void ClearAll()
{
//string[] keys = cache.Keys;
//List<string> keys = new List<string>(cache.Keys);
//for (int i = 0; i < keys.Count; i++)
//{
// Clear(keys[i]);
//}
foreach (var a in cache.Keys)
{
Clear(key);
}
}
//4 回收对象:使用完对象返回池中【从画面中消失】
//4.1即时回收对象
public void CollectObject(GameObject go)
{
go.SetActive(false);//本质:画面小时 设置属性
}
//4.2延时回收对象 等待一定的时间 协程
public void CollectObject(GameObject go,float delay)
{
StartCoroutine(CollectDelay(go, delay));
}
private IEnumerator CollectDelay(GameObject go, float delay)
{
yield return new WaitForSeconds(delay);
CollectObject(go);
}
}
单例模式抽象类(取自easytouch插件)
/// <summary>
/// Generic Mono singleton.
/// </summary>
using UnityEngine;
public abstract class MonoSingleton<T> : MonoBehaviour
where T : MonoSingleton<T>{
//2
private static T m_Instance = null;
//3
//设计阶段 写脚本 没有挂在物体上 希望脚本 单例模式
//运行时 需要这个脚本的唯一实例,第1次 调用instance
//第2,3,4,......次 调用instance
public static T instance{
get
{
if( m_Instance == null )
{
m_Instance = GameObject.FindObjectOfType(typeof(T)) as T;
if( m_Instance == null )
{
m_Instance =
new GameObject("Singleton of " + typeof(T).ToString(), typeof(T))
.GetComponent<T>();
//1 创建一个游戏物体 在层次面板中能看到
//2 把T这个脚本挂在这个游戏物体上,作为游戏物体的一个脚本组件
//3 GetComponent<T>(). 返回这个脚本组件,
// 这个脚本组件就是唯一实例,代码中用
m_Instance.Init();
}
}
return m_Instance;
}
}
// unity项目特点:
//设计阶段 写脚本 挂在物体上
//项目运行时【系统 帮我们 把脚本类 实例化了new】 脚本》》对象了
//项目运行时 在Awake时,从场景中找到 唯一实例 记录在 m_Instance中
private void Awake(){
if( m_Instance == null ){
m_Instance = this as T;
}
}
//提供 初始化 一种选择 Init ,Start
public virtual void Init(){}
//当应用程序 退出做 清理工作!单例模式对象=null
private void OnApplicationQuit(){
m_Instance = null;
}
}
对象池使用案例↓
using UnityEngine;
using System.Collections;
//TestGameObjectPool 把GameObjectPool 方法都调用一下
public class TestGameObjectPool : MonoBehaviour {
public GameObject[] prefabs;//记住赋值
public string[] names = {"Cube","Sphere" };
// Use this for initialization
GameObjectPool poolobj = null;
void Start () {
poolobj = GameObjectPool.instance;
//调用创建的方法
for (int i = 0; i < 3; i++)
{
Vector3 pos1 = new Vector3(Random.Range(-10, 10), 0,
Random.Range(-10, 10));
poolobj.CreateObject(names[0], prefabs[0],
pos1, Quaternion.identity);
}
}
// Update is called once per frame
void OnGUI () {
if (GUILayout.Button("创建"))
{
Vector3 pos1 = new Vector3(Random.Range(-10, 10), 0,
Random.Range(-10, 10));
poolobj.CreateObject(names[0], prefabs[0],
pos1, Quaternion.identity);
}
if (GUILayout.Button("释放 ,彻底删除"))
{
poolobj.ClearAll();
}
if (GUILayout.Button("回收"))
{
//找到某一个,回收
var go= GameObject.FindGameObjectWithTag(names[0]);
if (go != null) poolobj.CollectObject(go);
}
}
}