145 lines
5.0 KiB
C#
Raw Normal View History

2025-02-12 08:43:33 +08:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*******************************************************************************
*Create By CG
*Function _小池子
*******************************************************************************/
namespace ZXK.Framework
{
public class ObjectPool : MonoBehaviour
{
//这个对象池存储的游戏对象的预制体
public GameObject _Prefab;
//对象池最多能容纳多少个游戏对象。负数表示可以容纳无数个。
private const int _capacity = 15;
//从这个对象池中取出并正在使用的游戏对象。
public List<GameObject> _UsedGameObjectList = new List<GameObject>();
//存在这个对象池中没有被使用的游戏对象。
public List<GameObject> _UnusedGameObjectList = new List<GameObject>();
//这个对象池中正在使用和没有被使用的游戏对象的总数。
public int _TotalGameObjectCount { get => _UsedGameObjectList.Count + _UnusedGameObjectList.Count; }
/// <summary>
/// 从对象池获取一个对象,并返回这个对象。
/// 如果对象池有,从对象池中取出来用。
/// 如果对象池没有,则实例化该对象。
/// </summary>
/// <param name="position"></param>
/// <param name="rotation"></param>
/// <param name="parent"></param>
/// <returns></returns>
public GameObject Spawn(Vector3 position, Quaternion rotation, Transform parent = null)
{
//要实例化的游戏对象
GameObject go;
//如果对象池中有,则从对象池中取出来用。
if (_UnusedGameObjectList.Count > 0)
{
go = _UnusedGameObjectList[0];
_UnusedGameObjectList.RemoveAt(0);
_UsedGameObjectList.Add(go);
go.transform.localPosition = position;
go.transform.localRotation = rotation;
go.transform.SetParent(parent, false);
go.SetActive(true);
}
//如果对象池中没有,则实例化该对象。
else
{
go = Instantiate(_Prefab, position, rotation, parent);
_UsedGameObjectList.Add(go);
}
//如果该游戏对象身上继承MonoBehaviour的脚本中写了名叫OnSpwan的方法则会执行它们一次。
go.SendMessage("OnSpawn", SendMessageOptions.DontRequireReceiver);
return go;
}
/// <summary>
/// 隐藏指定的游戏对象,并把它回收进对象池中。
/// </summary>
/// <param name="go"></param>
public void Despawn(GameObject go)
{
if (go == null) return;
//遍历这个对象池中所有正在使用的游戏对象
for (int i = 0; i < _UsedGameObjectList.Count; i++)
{
if (_UsedGameObjectList[i] == go)
{
//如果这个对象池的容量不为负数且容纳的游戏对象已经满则把0号的游戏对象删除掉确保之后新的游戏对象能放入池子中。
if (_capacity >= 0 && _UnusedGameObjectList.Count >= _capacity)
{
Destroy(_UnusedGameObjectList[0]);
_UnusedGameObjectList.RemoveAt(0);
}
//把游戏对象回收到对象池中
_UnusedGameObjectList.Add(go);
_UsedGameObjectList.RemoveAt(i);
//如果该游戏对象身上继承MonoBehaviour的脚本写了名叫OnDespawn的方法则在回收的时候会执行一次。
go.SendMessage("OnDespawn", SendMessageOptions.DontRequireReceiver);
go.SetActive(false);
go.transform.SetParent(transform, false);
return;
}
}
}
/// <summary>
/// 把通过这个对象池生成的所有游戏对象全部隐藏并放入对象池中
/// </summary>
public void DespawnAll()
{
int count = _UsedGameObjectList.Count;
for (int i = 1; i <= count; i++)
{
Despawn(_UsedGameObjectList[0]);
}
_UsedGameObjectList.Clear();
}
/// <summary>
/// 预先往这个对象池中加载指定数量的游戏对象
/// </summary>
public void Preload(int amount = 1)
{
if (_Prefab == null) return;
if (amount <= 0) return;
for (int i = 1; i <= amount; i++)
{
GameObject go = Instantiate(_Prefab, Vector3.zero, Quaternion.identity);
go.SetActive(false);
go.transform.SetParent(transform, false);
_UnusedGameObjectList.Add(go);
go.name = _Prefab.name;
}
}
}
}