唐老师关于对物体分类的OOD的写法确实十分好,代码也耦合度也低,但是我有个简单的写法同样能实现一样的效果,所以我就充分发挥了一下主观能动性
相较于基本功能,这一版做出了如下改动
1.限制了对象池最大数量,多出来的要入池就会销毁掉
// 最大容量
private int maxCapacity = 100;
2.对生成出来的对象做出了二级分类更加清晰
public void SetParent(string name, GameObject obj) {
// 设置一级父对象
if (poolObjF == null)
poolObjF = new GameObject("一级分类");
// 查找或创建二级父对象
if (!poolObjS.ContainsKey(name)) {
//创建临时物体当作二级分类空对象,之后添加到字典中
GameObject tempObj = new GameObject("二级分类" + name);
tempObj.transform.parent = poolObjF.transform;
poolObjS[name] = tempObj;
}
obj.transform.parent = poolObjS[name].transform;
}
3.优化了清空池的方法
public void ClearPool() {
foreach (var item in pool) {
foreach (var obj in item.Value) {
GameObject.Destroy(obj);
}
}
pool.Clear();
poolObjF = null;
poolObjS.Clear();
}
4.添加了处理其他逻辑的函数,可以写一些重置AI状态的逻辑,会在拿出物体的时候调用
/// <summary>
/// 处理其他事情的逻辑可以写在这里面,比如重置怪物血量等
/// </summary>
public void OtherThing()
{
}
5.切换场景不销毁池物品调用方法即可
//public void DontDestoryPool(GameObject gameObject)
// {
// GameObject.DontDestroyOnLoad(gameObject);
//}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyPool : SingleBase<MyPool> {
// 一级父对象
private GameObject poolObjF;
// 二级父对象字典
private Dictionary<string, GameObject> poolObjS = new Dictionary<string, GameObject>();
// 抽屉字典 string => 物品名字,List => 具体物品
public Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>();
// 最大容量
private int maxCapacity = 100;
/// <summary>
/// 得到对象池中的物品
/// </summary>
/// <param name="path">预制体路径</param>
/// <returns></returns>
public GameObject GetObj(string path) {
GameObject obj = null;
// 如果有该物体,从抽屉中取出,如果没有则创建一个
if (pool.ContainsKey(path) && pool[path].Count > 0) {
obj = pool[path][0];
pool[path].RemoveAt(0);
}
else {
obj = GameObject.Instantiate(Resources.Load<GameObject>(path));
obj.name = path;
}
obj.SetActive(true);
//OtherThing();
return obj;
}
/// <summary>
/// 向对象池放回物品
/// </summary>
/// <param name="name">要放回的抽屉名</param>
/// <param name="obj">要放回的物品对象</param>
public void PutBackObj(string name, GameObject obj) {
SetParent(name, obj);
obj.SetActive(false);
// 如果有抽屉则放回去,没有则新建一个抽屉放进去,同时注意限制最大数量
if (pool.ContainsKey(name)) {
if (pool[name].Count < maxCapacity) {
pool[name].Add(obj);
}
else {
GameObject.Destroy(obj);
}
}
else {
pool.Add(name, new List<GameObject>() { obj });
}
}
public void SetParent(string name, GameObject obj) {
// 设置一级父对象
if (poolObjF == null)
poolObjF = new GameObject("一级分类");
// 查找或创建二级父对象
if (!poolObjS.ContainsKey(name)) {
//创建临时物体当作二级分类空对象,之后添加到字典中
GameObject tempObj = new GameObject("二级分类" + name);
tempObj.transform.parent = poolObjF.transform;
poolObjS[name] = tempObj;
}
obj.transform.parent = poolObjS[name].transform;
}
public void ClearPool() {
foreach (var item in pool) {
foreach (var obj in item.Value) {
GameObject.Destroy(obj);
}
}
pool.Clear();
poolObjF = null;
poolObjS.Clear();
}
/// <summary>
/// 处理其他事情的逻辑可以写在这里面,比如重置怪物血量等
/// </summary>
public void OtherThing()
{
}
}