开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2213

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 1640|回复: 48

[提笔写忧伤] 自写的对象池模板---- TObjectPool

[复制链接]  [移动端链接]
排名
1070
昨日变化
2

13

主题

1031

帖子

2761

积分

Rank: 9Rank: 9Rank: 9

UID
68430
好友
7
蛮牛币
9819
威望
0
注册时间
2015-1-14
在线时间
741 小时
最后登录
2018-5-25
发表于 2018-4-24 15:11:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 绝世love情缘 于 2018-4-25 10:26 编辑

自从前几天被邀请成为专栏专家后,一直没发过文章,说实在的仍不敢讲自己会多少东西,虽然负责过游戏很多模块了,但仍然有一些从未涉及编写过的功能,就像我昨晚在QQ空间发一份感慨一样“人生天地间,世路多坎坷!岁月伴寂寞,乾坤一哆嗦!”     ---世路多坎坷!所以不要停步不学习,才不能会被挫折打弯,对吧
好了,不废话了,摘了一段我自己写的对象池 TObjectPool,希望对有需要的小伙儿或美女有帮助


[C#] 纯文本查看 复制代码
/*===========================
 *Author:[Allen]
 *Purpose:对象池
 *Time:2017/10/16 10:39:47
============================*/
using System;
using System.Collections.Generic;
using UnityEngine;

public class TObjectPool<T> where T : class, new()
{
    public delegate T Creat(params object[] _params);                     //创建委托
    public delegate void Destroy(T t);                                                  //销毁委托

    private Creat pCreat = null;
    private Destroy pDestroy = null;

    private Queue<T> m_inactitveGameObjects;
    private List<T> m_actitveGameObjects;
    private object[] _params;

    //构建池
    public TObjectPool(int count, Creat pcreat, Destroy pdestroy, params object[] _vparams)
    {
        if (pcreat == null)
        {
            Debug.LogError("TObjectPool 对象池,委托为空");
            return;
        }
        pCreat = pcreat;
        pDestroy = pdestroy;
        _params = _vparams;

        count = Mathf.Clamp(count, 0, 100);
        m_inactitveGameObjects = new Queue<T>();
        for (int i = 0; i < count; ++i)
        {
            T t = pCreat(_params);
            m_inactitveGameObjects.Enqueue(t);
        }
        m_actitveGameObjects = new List<T>();
    }

    //销毁
    public void Release()
    {
        using (var enumerator = m_inactitveGameObjects.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                if (pDestroy != null)
                    pDestroy.Invoke(enumerator.Current);
            }
        }
        for (int i = 0; i < m_actitveGameObjects.Count; i++)
        {
            if (pDestroy != null)
                pDestroy.Invoke(m_actitveGameObjects[i]);
        }

        m_inactitveGameObjects.Clear();
        m_actitveGameObjects.Clear();
    }

    //获取池中激活数量
    public int GetActiveObjectCount()
    {
        return m_actitveGameObjects.Count;
    }

    //获得一个激活的
    public T OnActiveGameObject()
    {
        T ret = null;
        if (m_inactitveGameObjects.Count > 0)
        {
            ret = m_inactitveGameObjects.Dequeue();
        }
        else
        {

            Debug.LogErrorFormat("RoleId = {0} 实例化数量不够新加一个,当前正在使用数量 :{1}", _params[0],m_actitveGameObjects.Count);
            ret = pCreat(_params);
        }
        m_actitveGameObjects.Add(ret);
        return ret;
    }

    //转换激活对象转换为非激活对象
    public bool InActiveGameObject(T t)
    {
        if (t != null)
        {
            if (m_actitveGameObjects.Contains(t))
            {
                m_actitveGameObjects.Remove(t);
            }
            if (!m_inactitveGameObjects.Contains(t))
            {
                m_inactitveGameObjects.Enqueue(t);
            }
            return true;
        }
        return false;
    }

    //删除一个对象,不保存
    public bool DeleOneGameObject(T t)
    {
        if (t != null)
        {
            if (m_actitveGameObjects.Contains(t))
            {
                m_actitveGameObjects.Remove(t);
            }
            else if (m_inactitveGameObjects.Count > 0)
            {
                m_inactitveGameObjects.Dequeue();
            }
            if (pDestroy != null)
                pDestroy.Invoke(t);
            return true;
        }
        return false;
    }


    // 回收全部非激活
    public void InActiveGameAllObjects()
    {
        List<T> activeAll = new List<T>(m_actitveGameObjects);
        for (int i = 0; i < activeAll.Count; i++)
        {
            InActiveGameObject(activeAll[i]);
        }
    }
}




对象池原理:对象池中有两个列表,激活列表,非激活列表,元素创建,消亡时,都是根据这两个队列元素相互转化的

这里提供了对外构造函数 比如     TObjectPool<GameObjDate> pPool = new TObjectPool<GameObjDate>(3, GameObjDate.CreateObj, GameObjDate.ReleaseObj, path);


数字3,表示提供创建池时,同时创建3个元素到非激活列表中保存,比如有一群怪,需要在进入地图时创建出来,也就是说在loading进度条时就需要创建了,但是真正需要执行逻辑的时候才可以把他们激活,也就是这个3 的意义了~~后面几个参数依次是,创建函数委托,释放函数委托,跟创建函数需要的参数(不定参数)


使用对象池时:
当然首先讲需要激活时调用,还那怪物作比喻              GameObjDate obj = pPool.OnActiveGameObject();  就可以得到这个怪物了,
怪物死亡时,在调用              pPool.InActiveGameObject(obj); 就将他丢入非激活队列,以便再次复用

这个池对于现成的那种对象池插件讲它缺少一个功能的,就是对于非激活列表数量很多时,没有定时检测清理,为什么我没写呢,因为这个类没继承mono,也就是没有自身的定时功能,需要外部调用了,其次在游戏内应用对象池的地方,都是复用频率非常高的元素,比如战场角色,战场子弹,特效,音效以及其他等等,频率特别高,对于定时检测反而增加了负担,比如前一帧检测有10 个空闲角色的非激活状态,那么就清理掉吧,后一帧就有程序说现在需要创建出5个角色,那么就必须去重新创建了,得不偿失反而影响了效率,因此我没有写~
如果小伙伴有需要这个功能,自行添加

一下附件是我对于这个对象池使用,写了个简单个测试程序,以供下载











TObjectPool.zip

14.23 KB, 下载次数: 181

对象池


回复

使用道具 举报

6蛮牛粉丝
1489/1500
排名
1660
昨日变化

14

主题

200

帖子

1489

积分

Rank: 6Rank: 6Rank: 6

UID
158398
好友
3
蛮牛币
1456
威望
0
注册时间
2016-8-30
在线时间
575 小时
最后登录
2018-5-25
发表于 2018-4-24 17:17:52 | 显示全部楼层
感谢分享!

回复

使用道具 举报

4四处流浪
391/500
排名
6525
昨日变化
46

2

主题

63

帖子

391

积分

Rank: 4

UID
9302
好友
1
蛮牛币
649
威望
0
注册时间
2013-12-1
在线时间
148 小时
最后登录
2018-5-27
发表于 2018-4-24 22:32:18 | 显示全部楼层
这都要收费?我发几个免费的算了

点评

第一次发专家贴,已改免费了·~  发表于 2018-4-25 10:28

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1440/1500
排名
6183
昨日变化
45

0

主题

1069

帖子

1440

积分

Rank: 6Rank: 6Rank: 6

UID
267381
好友
3
蛮牛币
2350
威望
0
注册时间
2018-2-1
在线时间
179 小时
最后登录
2018-5-27

迈向小康

发表于 2018-4-24 22:47:47 | 显示全部楼层
谢谢分享

回复

使用道具 举报

5熟悉之中
887/1000
排名
2056
昨日变化
10

0

主题

35

帖子

887

积分

Rank: 5Rank: 5

UID
226426
好友
0
蛮牛币
1670
威望
0
注册时间
2017-6-12
在线时间
258 小时
最后登录
2018-5-26
发表于 2018-4-25 08:09:49 | 显示全部楼层
你是专栏作家还要收费  你自己感觉合适吗

点评

第一次发专家贴,免费了~~  发表于 2018-4-25 10:28

回复 支持 反对

使用道具 举报

4四处流浪
418/500
排名
7041
昨日变化
3

3

主题

120

帖子

418

积分

Rank: 4

UID
234410
好友
1
蛮牛币
520
威望
0
注册时间
2017-7-26
在线时间
133 小时
最后登录
2018-5-25
发表于 2018-4-25 08:49:55 | 显示全部楼层
收费这个。。。不是不能理解。。。不过这个东西他值这个 5 蛮牛吗。。。尽管 5 蛮牛不多。。。但是还是要吐槽一下。。。

点评

第一次发专家贴,免费了·~  发表于 2018-4-25 10:27

回复 支持 反对

使用道具 举报

排名
1070
昨日变化
2

13

主题

1031

帖子

2761

积分

Rank: 9Rank: 9Rank: 9

UID
68430
好友
7
蛮牛币
9819
威望
0
注册时间
2015-1-14
在线时间
741 小时
最后登录
2018-5-25
 楼主| 发表于 2018-4-25 10:30:17 | 显示全部楼层
第一次发专家贴,附件点币习惯了~~已修改成免费了,对不住童鞋们哈~

回复 支持 反对

使用道具 举报

排名
36253
昨日变化
15

0

主题

35

帖子

50

积分

Rank: 2Rank: 2

UID
277282
好友
0
蛮牛币
0
威望
0
注册时间
2018-4-16
在线时间
9 小时
最后登录
2018-5-3
发表于 2018-4-25 23:33:25 | 显示全部楼层
谢谢分享

回复

使用道具 举报

6蛮牛粉丝
1497/1500
排名
3187
昨日变化
23

37

主题

683

帖子

1497

积分

Rank: 6Rank: 6Rank: 6

UID
219600
好友
7
蛮牛币
2190
威望
0
注册时间
2017-4-27
在线时间
373 小时
最后登录
2018-5-26
发表于 2018-4-26 09:14:26 | 显示全部楼层
感谢分享

回复

使用道具 举报

5熟悉之中
520/1000
排名
4713
昨日变化
1

1

主题

93

帖子

520

积分

Rank: 5Rank: 5

UID
236305
好友
0
蛮牛币
704
威望
0
注册时间
2017-8-7
在线时间
160 小时
最后登录
2018-5-25
发表于 2018-4-26 10:03:50 | 显示全部楼层
学习一下~~

回复

使用道具 举报

7日久生情
2222/5000
排名
886
昨日变化

30

主题

454

帖子

2222

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
124569
好友
25
蛮牛币
10425
威望
0
注册时间
2015-10-4
在线时间
698 小时
最后登录
2018-5-25
发表于 2018-4-26 13:59:33 | 显示全部楼层
感谢分享

回复

使用道具 举报

4四处流浪
322/500
排名
7289
昨日变化
3

3

主题

42

帖子

322

积分

Rank: 4

UID
263289
好友
0
蛮牛币
454
威望
0
注册时间
2018-1-8
在线时间
127 小时
最后登录
2018-5-25
发表于 2018-4-27 09:35:21 | 显示全部楼层
感谢分享

回复

使用道具 举报

3偶尔光临
275/300
排名
8150
昨日变化
3

0

主题

62

帖子

275

积分

Rank: 3Rank: 3Rank: 3

UID
261148
好友
0
蛮牛币
385
威望
0
注册时间
2017-12-26
在线时间
83 小时
最后登录
2018-5-25
发表于 2018-4-27 09:36:26 | 显示全部楼层
我觉得收费也没什么不妥啊

回复 支持 反对

使用道具 举报

3偶尔光临
237/300
排名
9165
昨日变化
1

0

主题

59

帖子

237

积分

Rank: 3Rank: 3Rank: 3

UID
253671
好友
0
蛮牛币
155
威望
0
注册时间
2017-11-10
在线时间
72 小时
最后登录
2018-5-25
发表于 2018-4-27 16:36:39 | 显示全部楼层
学习学习寻

回复

使用道具 举报

2初来乍到
113/150
排名
12734
昨日变化
202

0

主题

17

帖子

113

积分

Rank: 2Rank: 2

UID
267262
好友
0
蛮牛币
157
威望
0
注册时间
2018-2-1
在线时间
38 小时
最后登录
2018-5-26

一贫如洗

发表于 2018-4-27 16:38:57 | 显示全部楼层
能解释下为什么激活用list 非激活用queue存吧,非激活能不能也用queue存呢
[发帖际遇]: yjh634901355 乐于助人,奖励 3 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关闭

站长推荐 上一条 /1 下一条

快速回复 返回顶部 返回列表