VR开发中其实很少用到对象池,不过这个思想虽然成熟却也是很值得学习的,所以闲下来就写了个简单的对象池。希望能达到抛砖引玉的作用。
不废话,上代码:
第一份代码是对象池的父类,由它派生出其他具体的对象池。
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 对象池
/// </summary>
public class Pool<T> : MonoBehaviour where T : new()
{
private static T instance = default(T);
/// <summary>
/// 单例
/// </summary>
public static T Instance
{
get
{
if (instance == null) instance = new T();
return instance;
}
}
/// <summary>
/// 对象池
/// </summary>
protected Stack<object> MyPool = new Stack<object>();
protected int Num { get { return MyPool.Count; } }
/// <summary>
/// 从对象池中获取对象
/// </summary>
/// <returns></returns>
public virtual object Get()
{
if (MyPool.Count > 0)
{
return MyPool.Pop();
}
else return new object();
}
/// <summary>
/// 将对象添加到对象池中
/// </summary>
/// <param name="t"></param>
public virtual void Deposit(object obj)
{
MyPool.Push(obj);
}
/// <summary>
/// 初始化取出的对象
/// </summary>
/// <param name="obj">取出的对象</param>
public virtual void Init(object obj)
{
}
}
下面这份代码则是具体的对象池,继承自上一份代码。
using UnityEngine;
/// <summary>
/// GameObject的对象池
/// </summary>
public class GOPool : Pool<GOPool>
{
public Vector3 StartPos = Vector3.zero;
/// <summary>
/// 目标预制体
/// </summary>
public GameObject TargetPrefab;
/// <summary>
/// 对象池中对象的预制体路径
/// </summary>
public string TargetPrefabPath;
public new GameObject Get()
{
if (MyPool.Count > 0)
{
GameObject go = MyPool.Pop() as GameObject;
Init(go);
return go;
}
else
return GameObject.Instantiate(Resources.Load("TargetPrefabPath") as GameObject);
}
public override void Deposit(object obj)
{
if (obj == null) return;
GameObject go = (GameObject)obj;
go.SetActive(false);
base.Deposit(go);
}
public override void Init(object obj)
{
GameObject go = obj as GameObject;
go.SetActive(true);
go.transform.position = StartPos;
}
}
使用起来不难。