unity对象池之引用技术
作者:互联网
推荐阅读:
专门写一篇文章来和大家分享一下引用技术,为什么呢?因为第一次听说这么名词,觉得高大上,不要害怕,其实道理挺简单的,待我细细来说明。
最近在做一个资源复用的功能,对于资源复用,一般能想到的解决办法就是使用对象池,需要的时候去池子里取。但是考虑效率消耗问题,想到了一个更优的方法:再引入一个对象池,共两个对象池,一个用来做资源对象池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
标签:count,end,objPool,对象,SetParent,unity,引用,newsid 来源: https://blog.csdn.net/shirln/article/details/106439912