游戏蛮牛学习群(纯技术交流,不闲聊):539178957
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2286

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

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

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

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

[复制链接]  [移动端链接]
排名
918
昨日变化
3

16

主题

1104

帖子

3031

积分

Rank: 9Rank: 9Rank: 9

UID
68430
好友
12
蛮牛币
10818
威望
0
注册时间
2015-1-14
在线时间
807 小时
最后登录
2018-8-17
发表于 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, 下载次数: 230

对象池

评分

参与人数 1鲜花 +1 收起 理由
a840171287 + 1 很给力!

查看全部评分


回复

使用道具 举报

7日久生情
1723/5000
排名
1489
昨日变化
3

14

主题

242

帖子

1723

积分

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

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

回复

使用道具 举报

5熟悉之中
663/1000
排名
4044
昨日变化
3

2

主题

74

帖子

663

积分

Rank: 5Rank: 5

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

点评

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

回复 支持 反对

使用道具 举报

7日久生情
1906/5000
排名
4258
昨日变化
6

0

主题

1334

帖子

1906

积分

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

UID
267381
好友
5
蛮牛币
3186
威望
0
注册时间
2018-2-1
在线时间
256 小时
最后登录
2018-8-6
发表于 2018-4-24 22:47:47 | 显示全部楼层
谢谢分享

回复

使用道具 举报

6蛮牛粉丝
1077/1500
排名
1621
昨日变化
6

0

主题

36

帖子

1077

积分

Rank: 6Rank: 6Rank: 6

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

点评

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

回复 支持 反对

使用道具 举报

5熟悉之中
573/1000
排名
5805
昨日变化
7

4

主题

166

帖子

573

积分

Rank: 5Rank: 5

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

点评

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

回复 支持 反对

使用道具 举报

排名
918
昨日变化
3

16

主题

1104

帖子

3031

积分

Rank: 9Rank: 9Rank: 9

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

回复 支持 反对

使用道具 举报

排名
37364
昨日变化
11

0

主题

35

帖子

50

积分

Rank: 2Rank: 2

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

回复

使用道具 举报

7日久生情
1796/5000
排名
2419
昨日变化
5

43

主题

741

帖子

1796

积分

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

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

回复

使用道具 举报

5熟悉之中
707/1000
排名
3650
昨日变化
9

1

主题

122

帖子

707

积分

Rank: 5Rank: 5

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

回复

使用道具 举报

7日久生情
2488/5000
排名
725
昨日变化
2

30

主题

525

帖子

2488

积分

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

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

回复

使用道具 举报

4四处流浪
425/500
排名
6116
昨日变化
3

3

主题

48

帖子

425

积分

Rank: 4

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

回复

使用道具 举报

4四处流浪
306/500
排名
7703
昨日变化
2

0

主题

65

帖子

306

积分

Rank: 4

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

回复 支持 反对

使用道具 举报

4四处流浪
368/500
排名
6815
昨日变化
7

0

主题

75

帖子

368

积分

Rank: 4

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

回复

使用道具 举报

3偶尔光临
174/300
排名
10290
昨日变化
4

0

主题

25

帖子

174

积分

Rank: 3Rank: 3Rank: 3

UID
267262
好友
0
蛮牛币
267
威望
0
注册时间
2018-2-1
在线时间
55 小时
最后登录
2018-8-17
发表于 2018-4-27 16:38:57 | 显示全部楼层
能解释下为什么激活用list 非激活用queue存吧,非激活能不能也用queue存呢
[发帖际遇]: yjh634901355 乐于助人,奖励 3 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

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

本版积分规则

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