内存优化:对象池
2020-11-07 本文已影响0人
GameObjectLgy
核心方法:
1、初始化对象池:实例化后,全部隐藏起来
2、公有接口,得到对象:返回一个对象,并且将对象在场景中显示。
3、公有接口,隐藏对象:在场景中隐藏对象,并且将对象放进对象池中。
说明:如果游戏中需要很多类型游戏物体的对象池,则可以增加一个对象池管理单例类,统一管理所有类型的对象池。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using Object = UnityEngine.Object;
public class GameObjectPool
{
private List<GameObject> _acticveList;
private List<GameObject> _inactiveList;
private bool _isDestroying;
private int _minNum;
private GameObject _prefab;
private GameObject _selfGO;
private DateTime _spawnTime;
private readonly int _useFrequency = 5;
public void Init(GameObject prefab, Transform parent, int preloadCount, bool autoDestroy)
{
_isDestroying = false;
_minNum = preloadCount;
_acticveList = new List<GameObject>(preloadCount);
_inactiveList = new List<GameObject>(preloadCount);
_prefab = prefab;
_selfGO = new GameObject(_prefab.name + "Pool");
_selfGO.transform.SetParent(parent);
Preload(preloadCount);
if (autoDestroy)
AutoDstroy();
}
private async void AutoDstroy()
{
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(1));
var spendTime = (_spawnTime - DateTime.Now).Seconds;
if (spendTime >= _useFrequency && !_isDestroying)
{
_isDestroying = true;
StartDestroy();
}
}
}
private async void StartDestroy()
{
GameObject go = null;
while (_inactiveList.Count > _minNum)
{
await Task.Delay(100);
go = _inactiveList[0];
_inactiveList.Remove(go);
Object.Destroy(go);
}
_isDestroying = false;
}
private void Preload(int count)
{
GameObject temp = null;
for (var i = 0; i < count; i++)
{
temp = SpawnNew();
_inactiveList.Add(temp);
temp.SetActive(false);
}
}
public GameObject Spawn()
{
_spawnTime = DateTime.Now;
GameObject temp = null;
if (_inactiveList.Count > 0)
{
temp = _inactiveList[0];
_inactiveList.Remove(temp);
temp.SetActive(true);
}
else
{
temp = SpawnNew();
}
_acticveList.Add(temp);
return temp;
}
private GameObject SpawnNew()
{
return Object.Instantiate(_prefab, _selfGO.transform);
}
public void Despawn(GameObject go)
{
if (_acticveList.Contains(go))
{
_acticveList.Remove(go);
_inactiveList.Add(go);
go.SetActive(false);
}
}
public int GetActiveNum()
{
return _acticveList.Count;
}
}
使用说明:
Init(GameObject prefab, Transform parent, int preloadCount, bool autoDestroy)
public GameObject Spawn()
public void Despawn(GameObject go)
int GetActiveNum()