内存优化:对象池

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()

上一篇下一篇

猜你喜欢

热点阅读