2025-02-12 08:43:33 +08:00

145 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}
}