MonoSingleton
—— 单例基类
任何继承自 MonoSingleton 泛型基类的脚本/类 都是单例类
using UnityEngine;
/// <summary>/// 泛型单例基类 —— 任何继承自该类的类,都是单例类/// </summary>/// <typeparam name="T">泛型</typeparam>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
private static T instance;
public static T Instance
{
get {
if (instance == null)
{
instance = FindObjectOfType(typeof(T)) as T;
if (instance == null) instance = new GameObject("Chinar Single of " + typeof(T).ToString(), typeof(T)).GetComponent<T>();
}
return instance;
}
}
private void Awake() {
if (instance == null) instance = this as T;
}
private void OnApplicationQuit() {
instance = null;
}
}
2
ObjectPool —— 对象池
新建一个脚本 ObjectPool 继承自泛型基类 MonoSingleton《ObjectPool》
是以 ObjectPool 就会是一个单例类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>/// 对象池(重复调用/使用的游戏物体) 子弹,技能,导弹,敌人/// </summary>
public class ObjectPool : MonoSingleton<ObjectPool>
{
//字段 池 技能预设物(因为一个技能可能有多个预制件) 技能的复用性
private Dictionary> cache = new Dictionary<string, List<GameObject>();
int i = 0; //标记 0
/// <summary> /// 创建显示对象 /// </summary>
/// <returns>The object.</returns>
/// <param name="key">对象名称</param>
/// <param name="go">对象的预制件</param>
/// <param name="position">对象的新位置</param>
/// <param name="quaternion">对象的角度</param>
public GameObject CreateObject(string key, GameObject go, Vector3 position, Quaternion quaternion) {
GameObject tempgo = cache.ContainsKey(key) ? cache[key].Find(p => !p.activeSelf) : null; //返回池中未激活的对象,所有都被激活就返回空,赋值给临时对象
if (tempgo != null) //如果临时对象不为空
{
tempgo.transform.position = position; //设置位置
tempgo.transform.rotation = quaternion; //旋转信息
}
else //否则,就是空了。(也就是没能从池子里取出对象)
{
tempgo = Instantiate(go, position, quaternion); //那就根据传入的预设物,生成一个新物体
print("实例化物体数量:" + i++);
if (!cache.ContainsKey(key)) //池中没有键
{
cache.Add(key, new List<GameObject>()); //新建一个 列表
}
cache[key].Add(tempgo); //给字典中的列表加入/add 临时物体,如果有键就直接添加了
}
tempgo.SetActive(true); //并启用临时物体
return tempgo; //返回
}
/// <summary> /// 直接回收 /// </summary>
/// <param name="go">Go.</param>
public void CollectObject(GameObject go)
{
go.SetActive(false);
}
/// <summary> /// 延迟回收 /// </summary>
/// <param name="go">Go.</param>
/// <param name="delay">Delay.</param>
public void CollectObject(GameObject go, float delay) {
StartCoroutine(Collect(go, delay));
}
private IEnumerator Collect(GameObject go, float delay)
{
yield return newWaitForSeconds(delay);
CollectObject(go);
}
/// <summary> /// 释放资源 /// </summary>
/// <returns>The clear.</returns>
/// <param name="key">Key.</param>
public void Clear(string key) {
if (cache.ContainsKey(key))
{
//Destroy当中所有的对象
for (int i = 0; i < cache[key].Count; i++)
{
Destroy(cache[key][i]);
}
//清除键当中的所有值
//cache[key].Clear();
//清除这个键(键值一起清除)
cache.Remove(key);
}
}
/// <summary> /// 释放所有对象池 /// </summary>
public void ClearAll() {
var list = new List<string>(cache.Keys);
for (int i = 0; i < list.Count; i++)
{
Clear(list[i]);
}
}
}
3
PoolTest —— 测试对象池的使用
新建一个脚本 PoolTest 用来测试对象池的使用
using UnityEngine;
/// <summary>
/// 测试对象池的调用
/// </summary>
public class PoolTest : MonoBehaviour{
GameObject go; //临时对象
GameObject item; //临时对象池对象
voidStart() {
go = Resources.Load<GameObject>("Cube"); //在Resources文件目录下做一个Cube预设物
}
voidUpdate() {
if (Input.GetKey(KeyCode.Space)) //按下空格创建一个Cube
{
item = ObjectPool.Instance.CreateObject("Object1", go, Vector3.zero, new Quaternion(0, 0, 0, 0));
item.transform.position += new Vector3(0, 0, 1);
}
if (Input.GetMouseButtonDown(0)) //按下左键执行回收对象
{
if (item != null)
{
ObjectPool.Instance.CollectObject(item, 0.2f);
}
}
if (Input.GetMouseButtonDown(1)) //按下右键执行清除已经生成的对象
{
ObjectPool.Instance.Clear("Object1");
}
}
}