最近lol手游持续火热中,最近又上线了一个新活动,完成任务,免费送小法。当然。老司机已经成功获得小法一个。
恰巧,最近工作上也在做一個活動,和lol上面这个任务有类似功能——进度条。注意看,上面进度条的位置等间距,但是相邻两个差值却不一样。今天就带大家来实现这种功能,话不多说,赶紧开始吧!
前言
游戏中,经常会使用进度条的方式,显示玩家当前到目标的进度。进度条的显示方式,更加直观的体现了距离,但是如何在准确的体现进度,就显得尤为重要了。如果只有单纯的一个目标点,显示进度的方式就特别简单,只需要用目标值/当前值获得。如果目标点的个数不固定,且每相邻两个目标点需要达到的差值也不固定,这时候该如何的显示进度呢?
搭建UI
首先创建一个空物体,作为整个进度信息的父节点,命名為prog
为了更加准确的让玩家知道当前进度值,通常我们会用一个Text组件显示玩家当前完成数。创建记录完成数量的游戏对象,吗,命名为Total,num显示具体的完成数量。
接下来,创建一个Slider对象,用来显示进度条。
最后,创建5个宝箱,作为单个目标点。
思路分析
由于进度条上面的宝箱数量不固定,所以两个宝箱之间的距离和进度值也不固定,都随宝箱数量变化。
首先,我们需要知道宝箱进度条总长度,可以通过移动记录空物体在起始位置(x=232)和终点位(x=232)置的值,做差得到。
232-(-239.1) = 471.1
现在,我们先来研究下怎么计算两宝箱之间的距离。设宝箱数量为n(n=5)用总长度(x= 471.1)除以宝箱分割数量得到,
471.1/n = 471.1/5 = 94.22
有了距离和起始位置,可以算出第一个宝箱以及第n个宝箱的位置。
第1个宝箱位置:-239.1 + 94.22*1 = -144.88
第2个宝箱位置:-239.1 + 94.22*2 = -50.66
第n(n=5)个宝箱位置:-239.1 + 94.22n = -239.1 + 94.225 = 232
获得数据
新建一个空物体,帮助查看进度条的起始位置信息
用同样的方式,获得终点位置信息
等间距生成宝箱
等间距生成宝箱代码如下:
local startPosX = -407.9 --进度条起始位置
local progLength = 523.7 --进度条总长度
local tasknumber = {8,20,45,50,58} --每个包厢需要达到的数量,长度即宝箱数
--初始化,获取组件
local function Init()
self.normalButton = {}
self.normalImage = {}
self.normalText = {}
for i = 1, 5 do
self.normalButton[i] = transform:Find(string.format("prog/box/normal%s", i)):GetComponent("Button")
self.behaviour:AddClick(self.normalButton[i], OnClick)
self.normalImage[i] = self.normalButton[i].transform:GetComponent("Image")
self.normalText[i] = transform:Find(string.format("prog/box/normal%s/num", i)):GetComponent("Text")
end
end
--动态生成宝箱位置
local function RefreshBoxPos()
local len = #tasknumber
local stepLength = progLength/len
for i=1,len do
self.normalButton[i].gameObject.transform.localPosition = Vector2.New(startPosX+i*stepLength,8)
end
for i=1,5 do
self.normalButton[i].gameObject:SetActive(i <= len)
end
end
接下来就是计算进度了,如果单纯用百分比来计算,就会出现如下情况:进度条和实际进度对不上。
精准计算进度值
为了避免这个情况发生,还是得单独间隔计算进度。即根据任务数量完成来判断某段进度的完成情况。
local perProgVlaue = 1/#tasknumber -- 两个宝箱之间的进度值0-1
local completedNum -- 已经完成的数量
--初始化:获取组件
local function Init()
self.normalImageProgress = transform:Find("prog/slider"):GetComponent("Slider")
end
--显示进度值
local function RefreshTopProg()
for i = 1, #tasknumber do
if completedNum >= tasknumber[i] then
self.normalImageProgress.value = self.normalImageProgress.value + perProgVlaue
else
local lastNum = tasknumber[i-1] or 0 --1
local currStepValue = perProgVlaue*((completedNum-lastNum)/(tasknumber[i]-lastNum))
self.normalImageProgress.value = self.normalImageProgress.value + currStepValue
break
end
end
end