欢迎来到我的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注同名公众号:Java学习之道

unity对象池之引用技术

  |   0 评论   |   0 浏览

推荐阅读:

专门写一篇文章来和大家分享一下引用技术,为什么呢?因为第一次听说这么名词,觉得高大上,不要害怕,其实道理挺简单的,待我细细来说明。

最近在做一个资源复用的功能,对于资源复用,一般能想到的解决办法就是使用对象池,需要的时候去池子里取。但是考虑效率消耗问题,想到了一个更优的方法:再引入一个对象池,共两个对象池,一个用来做资源对象池objPool,一个是将实例化资源的所在的父类所用到的所有的对象作为另一个池itemPool。

用文字描述可能听不太懂,给大家举个例子吧:

玩家时装展示榜单:该榜单是个循环列表,大致5个item的样子。首先判断需要显示的时装是否存在objPool,不存在,则实例化并保存在objPool里。存在则取出对象,SetParent到需要显示的item上。但是,使用这种方式会出现一个问题:

当同一页面的两个及以上玩家时装相同时,会导致穿戴该时装的只有最后一个玩家时装时存在的,同一界面其他玩家没有时装,这就是SetParent的结果,因为资源只有一个,但是却有几个地方SetParent了。没有实例化,仅仅SetParent,当然结果会停留在最后一次SetParent。

对于上面的问题,对象池里面的对象都是唯一的,如果某个对象会同时在两个及以上的的地方同时使用时,又该怎么办呢?这时候就要用到引用技术了。

引用技术:当某个对象需要被同时在多处使用时,为了保证每个地方都能使用,它支持去对象池去取该对象,如果存在则直接拿出来使用,不存在则按照:对象的名字+序号来区分该对象,名字如下:
cat_1,cat_2,dog_1,等等。现在我们的目标很清晰了,重点是计算序号(count):

local count = 0 
for 对象池 do
	 if 对象显示在面板 then
		count = count +1
	end
end

在unity中,判断是否显示在面板上的方法:

activeInHierarchy

功能实现方法:

 newsid = 1001 + index--TODO
    if args[1] and args[1] == newsid then
        --一样
    else
        if args[2] then
            SetActive(objPool[tonumber(args[1])][tonumber(args[2])], false)
        end
        local count = 0
        for k, v in pairs(objPool[newsid] or {}) do
            if v.activeInHierarchy then
                count = count + 1
            end
        end
        local data = { sid = newsid, star = 5 }
        local obj = objPool[newsid] and objPool[newsid][count] or herobase.SetHeroRes(data, go, 0.5)
        obj.transform:SetParent(render.mold.transform)
        obj.transform.localPosition = Vector3.New(0, -280, 0)
        if objPool[newsid] == nil then
            objPool[newsid] = {}
        end
        objPool[newsid][count] = obj
        renderObj[go] = newsid .. "|" .. count
        SetActive(obj, true)
    end

标题:unity对象池之引用技术
作者:shirln
地址:https://mmzsblog.cn/articles/2020/07/28/1595904465580.html
-----------------------------
如未加特殊说明,此网站文章均为原创。
转载须在文章起始位置标注作者及原文连接,否则保留追究法律责任的权利。

个人微信公众号 ↓↓↓                 

微信搜一搜爱上游戏开发