【unity资源管理】内存池

内存池思想:创建对象时,先检查内存池中是否有缓存对象,如果没有再创建新的。 删除对象时,不立即销毁,缓存一段时间,避免重复创建,提升执行效率,用空间换时间的做法。常用怪、NPC、技能特效、血条等。


基本功能:保存,获取,智能删除。


实现方式

基本对象

public class PoolItem
{
	public string Name;//文件名+ID作为关键字 因为怪等会同时存在多个
	public GameObject Obj;
	public bool IsFree = false;
	public float RecycleTime;//时间戳,被回收时的时间
	public bool IsUpdated=false;    //Destroy在update后执行,所以回收的对象在一次update后可以使用
	public bool IsForever=false;//是否持久存在,如玩家血条,不需要删除

    public PoolItem()
    {
        Name = "";
        Obj = null;
        IsFree = false;
        RecycleTime = 0;
        IsUpdated = false;
        IsForever = false;
    }

    public PoolItem(string name,GameObject obj,bool forever)
    {
        Name = name;
        Obj = obj;
        IsFree = true;
        RecycleTime = Time.fixedTime;
        IsUpdated = false;
        IsForever = forever;
    }

    public bool CanUse      //判断是否可以使用,更新过一次的才能用
    {
        get { return IsFree && IsUpdated; }
    }

    public bool CanDel        //判断当前对象是否可以删除,超过一定时间没使用的删除
    {
        get { return !IsForever && IsFree && (Time.fixedTime - RecycleTime > 30); }
    }
}
执行添加、删除操作

private List<PoolItem> _itemList = new List<PoolItem>();

    private void _delItem(int index, bool immediate = false)    //真正删除对象 只在这一个地方执行
    {
        if (immediate)
            DestroyImmediate(_itemList[index].Obj);
        else
            DestroyObject(_itemList[index].Obj);
        _itemList.RemoveAt(index);
    }

    private void _addItemList(PoolItem item)        //添加对象
    {
        _itemList.Add(item);
    }
获取缓存对象

//获取缓存对象 创建时先检查是否有可用缓存
    public PoolItem GetFreeItem(string filename)
    {
        for (int i = 0; i < _itemList.Count; i++)
        {
            PoolItem item = _itemList[i];
            if (item.CanUse && item.Name.IndexOf(filename, System.StringComparison.Ordinal) >= 0)
            {
                item.IsFree = false;
                return item;
            }
        }
        return null;
    }
保存缓存对象
//回收对象 代替删除
    public void RecycleItem(string effname, GameObject gb, bool isForever = false)
    {
        PoolItem item = _getPoolItem(gb) ?? new PoolItem(effname,gb,isForever);
        _addItemList(item);
        gb.transform.parent = transform;//调整节点
        gb.SetActive(false);
    }
private PoolItem _getPoolItem(GameObject gb)
    {
        PoolItem item = null;
        for (int i = 0; i < _itemList.Count; i++)
        {
            var item2 = _itemList[i];
            if (item2.Obj == gb)
            {
                item = item2;
                break;
            }
        }
        return item;
    }
 
 
根据时间删除不需要的缓存对象 

void Update()
	{
		for(int i =0;i<_itemList.Count;)
		{
			var item=_itemList[i];
			item.IsUpdated=true;
		    if(item.CanDel)
		        _delItem(i);
		    else
		        i++;
		}
	}
特殊条件释放所有不用资源

//释放所有资源 一般在切换场景时操作
    public void UnloadAllFree()
    {
        for (int i = 0; i < _itemList.Count; )
        {
            var item = _itemList[i];
            if (item.IsFree)
                _delItem(i, true);
            else
                i++;
        }
    }
对perfab的处理:加载出来的资源很多需要在使用时动态改变一些参数,或设置显隐等,回收时需要根据实际情况重置。

这样一个简单的内存池功能就实现了,实际应用中还可以控制不同对象缓存时间,设置优先级控制大小等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值