对象池

private Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>();//对象池
private Dictionary<string, List<int>> poolId = new Dictionary<string, List<int>>();//对象池对应Id
private ObjectPool()
{
//私有构造方法
}
///各种操作方法
/// <summary>
/// 初始化一个内存池
/// </summary>
/// <param name="gameObject">要添加进对象池的对象</param>
public void InitObjectPool(GameObject gameObject)
{
if (pool.ContainsKey(gameObject.name))
{
Debug.LogError("警告:" + gameObject.name + "该对象池已经存在");
return;
}
pool.Add(gameObject.name, new List<GameObject>());//初始化该类物体的池
poolId.Add(gameObject.name, new List<int>());//初始化该类物体的池id
GameObject game = Instantiate(new GameObject(), transform.position, Quaternion.identity, transform);//创建一个空物体作为所有同类对象根节点。
game.SetActive(false);
Init(gameObject.name, game);//将物体添加到对象池
game = Instantiate(gameObject, transform.position, Quaternion.identity, pool[gameObject.name][0].transform);//初始化是会实例化一个对象,好用于后面创建同类物体
Init(gameObject.name, game);

}
/// <summary>
/// 初始化对象池,方法重载
/// </summary>
/// <param name="key">对象池key</param>
/// <param name="gameObject">要添加进对象池的对象</param>
public void InitObjectPool(string key, GameObject gameObject)
{
if (pool.ContainsKey(key))
{
Debug.LogError("警告:" + key + "该对象池已经存在");
return;
}
pool.Add(key, new List<GameObject>());
poolId.Add(key, new List<int>());
GameObject game = Instantiate(new GameObject(), transform.position, Quaternion.identity, transform);
game.SetActive(false);
Init(key, game);

game = Instantiate(gameObject, transform.position, Quaternion.identity, pool[key][0].transform);
Init(key, game);


}
/// <summary>
/// 私有,初始化
/// </summary>
/// <param name="key"></param>
/// <param name="gameObject"></param>
private void Init(string key, GameObject gameObject)
{
//设置每个子物体名字
gameObject.name = key + pool[key].Count;
//gameObject.SetActive(false);//隐藏
poolId[key].Add(pool[key].Count);//设置空物体对应id为对应pool 中list长度
pool[key].Add(gameObject);
}

/// <summary>
/// 从对象池中获取一个对象
/// </summary>
/// <param name="key">对象池Key</param>
/// <returns></returns>
public GameObject GetGameObject(string key)
{
if (pool.ContainsKey(key))
{
if (poolId[key].Count <= 2)//表示池中没有多余对象,需要创建。根节点,与初始化了一个对象,所以count为2;
{
GameObject game = Instantiate(pool[key][1], transform.position, Quaternion.identity, pool[key][0].transform);//根据1索引创建对象
game.name = key + pool[key].Count;
poolId[key].Add(pool[key].Count);//添加对应id
pool[key].Add(game);
}
int i = poolId[key][^1];//获取最后一个id,这个id对应Pool,list里面的对象;
poolId[key].RemoveAt(poolId[key].Count - 1);//删除最后一个id
return pool[key][i];//返回id对应个元素
}
else
{
Debug.LogError("警告:不存在" + key + "对象池");
return null;
}

}
/// <summary>
/// 从对象池中获取一个对象
/// </summary>
/// <param name="name">对象池Key</param>
/// <param name="parent">设置父物体</param>
/// <returns></returns>
public void GetGameObject(string key, GameObject parent)
{
if (pool.ContainsKey(key))
{
if (poolId[key].Count <= 2)
{
GameObject game = Instantiate(pool[key][1], transform.position, Quaternion.identity, pool[key][0].transform);
game.name = key + pool[key].Count;
poolId[key].Add(pool[key].Count);
pool[key].Add(game);
}
int i = poolId[key][^1];
poolId[key].RemoveAt(poolId[key].Count - 1);
pool[key][i].transform.SetParent(parent.transform);//设置父物体
pool[key][i].transform.position = parent.transform.position;//初始化位置为父物体位置
}
else
{
Debug.LogError("警告:不存在" + key + "对象池");
}

}
/// <summary>
/// 获取指定个数对象
/// </summary>
/// <param name="key">对象池key</param>
/// <param name="num">数量</param>
/// <returns></returns>
public List<GameObject> GetGameObjects(string key, int num)
{
List<GameObject> list = new List<GameObject>();
if (pool.ContainsKey(key))
{
for (int i = 0; i < num; i++)
{
list.Add(GetGameObject(key));
}
}
else
{
Debug.LogError("警告:不存在" + key + "对象池");
}
return list;
}

/// <summary>
/// 销毁
/// </summary>
/// <param name="key">对象池key</param>
/// <param name="gameObject">需要销毁的对象</param>
public void Destroy(string key, GameObject gameObject)
{
if (pool.ContainsKey(key))
{
int index = pool[key].FindIndex(x => x.gameObject == gameObject);//寻找对象在对象池中的Id
if (index != -1)//未找到,表示非对象池创建对象
{
poolId[key].Add(index);//添加回到poolId
gameObject.transform.SetParent(pool[key][0].transform);
}
else//将该对象加入对象池
{
gameObject.name = key + pool[key].Count;
poolId[key].Add(pool[key].Count);
pool[key].Add(gameObject);
gameObject.transform.SetParent(pool[key][0].transform);
}

}
else
{
Debug.LogError("警告:未找到" + key + "所对应对象池,该对象池不存在");
}
}
/// <summary>
/// 销毁
/// </summary>
/// <param name="gameObject">需要销毁的对象</param>
public void Destroy( GameObject gameObject)
{
string key = gameObject.name;
if (pool.ContainsKey(key))
{
int index = pool[key].FindIndex(x => x.gameObject == gameObject);//寻找对象在对象池中的Id
if (index != -1)//未找到,表示非对象池创建对象
{
poolId[key].Add(index);//添加回到poolId
gameObject.transform.SetParent(pool[key][0].transform);
}
else//将该对象加入对象池
{
gameObject.name = key + pool[key].Count;
poolId[key].Add(pool[key].Count);
pool[key].Add(gameObject);
gameObject.transform.SetParent(pool[key][0].transform);
}

}
else
{
Debug.LogError("警告:未找到" + key + "所对应对象池,该对象池不存在");
}
}

/// <summary>
/// 清空所有对象池
/// </summary>
public void CleaAll()
{
foreach (string key in pool.Keys)
{
pool[key].Clear();
}

}
/// <summary>
/// 清空指定对象池
/// </summary>
/// <param name="key">对象池key</param>
public void CleaOne(string key)
{
if (pool.ContainsKey(key))
{
pool[key].Clear();
}
else
{
Debug.LogError("警告:不存在" + key + "对象池");
}

}
/// <summary>
/// 重置对象池(删除所有对象池,非清空)
/// </summary>
public void ResetPool()
{
pool.Clear();
}
/// <summary>
/// 使用对象池(获取唯一实例对象)
/// </summary>
/// <returns></returns>
public static ObjectPool CreatObjectPool()
{
return MonoSingleton<ObjectPool>.SingleTon;
}

posted @ 2023-08-18 18:46  Trigger_F  阅读(13)  评论(0编辑  收藏  举报