Unity Xlua热更新框架(八):对象池

13. 对象池

13-1. 对象池

  • 作用:减少对象创建和销毁的次数,让对象可以重复使用
  • 对象特点:使用频率高、使用次数多
  • 对象类型:AssetBundle需要Unload、GameObject(UI、Entity、Sound)需要Destroy

传统对象池:

  • 原理:先创建一定数量的对象、使用时从池子取,用完了还回去
  • 特点:相同对象、多次使用

我们的对象池:

  • 特点:对象可以是多种类型、短时间内可重复使用、过期自动销毁
  • 设计原理:池内不创建对象,对象在外部创建,使用完放入对象池,再次使用从对象池取

创建Framework/ObjectPool/PoolObject

using UnityEngine;

//专门用来存放ObjectPool里放置的不同对象的数据类
public class PoolObject
{
   
   
    //具体对象
    public Object Object;
    
    //对象名字
    public string Name;
    
    //最后一次使用时间,,,针对不同类型的对象有不同的有效时长,超过有效时长就销毁
    public System.DateTime LastUseTime;

    //生成实例,放入池子时,会记录一下上一次的使用时间
    public PoolObject(string name, Object obj)
    {
   
   
        Name = name;
        Object = obj;
        LastUseTime = System.DateTime.Now;
    }
}

对于AssetBundle和GameObject的存和取都不相同。AssetBundle不需要设置非激活。
创建Framework/ObjectPool/PoolBase

using System.Collections.Generic;
using UnityEngine;

public class PoolBase : MonoBehaviour
{
   
   
    //自动释放时间/s
    protected float m_ReleaseTime;
    
    //上次释放资源的时间/毫微妙 1(秒) = 10000000(毫微秒)
    protected long m_LastReleaseTime = 0;
    
    //真正的对象池
    protected List<PoolObject> m_Objects;

    public void Start()
    {
   
   
        m_LastReleaseTime = System.DateTime.Now.Ticks;
    }
    
    //初始化对象池
    public void Init(float time)
    {
   
   
        m_ReleaseTime = time;
        m_Objects = new List<PoolObject>();
    }

    //取出对象
    public virtual Object Spawn(string name)
    {
   
   
        foreach (PoolObject po in m_Objects)
        {
   
   
            if (po.Name == name)
            {
   
   
                //放在池子里的一定是还没有用到的,用到的就拿出来
                m_Objects.Remove(po);
                return po.Object;
            }
        }
        return null;
    }
    
    //回收对象
    public virtual void UnSpawn(string name, Object obj)
    {
   
   
        PoolObject po = new PoolObject(name, obj);
        m_Objects.Add(po);
    }
    
    //释放,父类什么都不做
    public virtual void Release()
    {
   
   
        
    }

    private void Update()
    {
   
   
		//父类需要按给定时间执行一次Release,但是到底释放没有,需要根据继承父类的子类来确定,其内部的时间是否到了销毁时间
        if (System.DateTime.Now.Ticks - m_LastReleaseTime >= m_ReleaseTime * 10000000)
        {
   
   
            //刷新时间
            m_LastReleaseTime = System.DateTime.Now.Ticks;
            Release();
        }
    }
}
public class GameObjectPool : PoolBase
{
   
   
    //去物体:在池子中查找,如果有物体就激活,没有返回null
    public override Object Spawn(string name)
    {
   
   
        Object obj = base.Spawn(name);
        if (obj == null)
            return null;
        
        GameObject go = obj as GameObject;
        go.SetActive(true);
        return obj;
    }

    //存物体:把物体设置非激活,然后放进池子回收
    public override void UnSpawn(string name, Object obj)
    {
   
   
        GameObject go = obj as GameObject;
        go.SetActive(false);
        go.transform.SetParent(this.transform, false);
        base.UnSpawn(name, obj);
    }

    public override void Release()
    {
   
   
        base.Release();
        foreach (PoolObject item in m_Objects)
        {
   
   
            if (System.DateTime.Now.Ticks - item.LastUseTime.Ticks >= m_ReleaseTime * 10000000)
            {
   
   
                Debug.Log("GameObjectPool release time:" + System.DateTime.Now);
                Destroy(item.Object);
                m_Objects.Remove(item);
                //因为删除了list一项之后,不能用迭代器了,需要递归一下跳出
                Release();
                return;
            }
        }
    }
}
public class AssetPool : PoolBase
{
   
   
    public override UnityEngine.Object Spawn(string name)
    {
   
   
        return base.Spawn(name);
    }

    public override void UnSpawn(string name, UnityEngine.Object obj)
    {
   
   
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值