PGRData/Script/matrix/xcommon/XUiHelper.lua
2024-09-01 22:49:41 +02:00

2009 lines
No EOL
66 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local math = math
local string = string
local tonumber = tonumber
local mathFloor = math.floor
local mathCeil = math.ceil
local mathMin = math.min
local mathMax = math.max
local stringFormat = string.format
local stringSub = string.sub
local stringFind = string.find
local stringGsub = string.gsub
local tableSort = table.sort
local tableInsert = table.insert
local Vec3Lerp = CS.UnityEngine.Vector3.Lerp
local MathLerp = CS.UnityEngine.Mathf.Lerp
local CSTextManagerGetText = CS.XTextManager.GetText
local CSVector2 = CS.UnityEngine.Vector2
local CSVector3 = CS.UnityEngine.Vector3
local CSQuaternion = CS.UnityEngine.Quaternion
local STR_MONTH = CSTextManagerGetText("Mouth")
local STR_WEEK = CSTextManagerGetText("Week")
local STR_DAY = CSTextManagerGetText("Day")
local STR_HOUR = CSTextManagerGetText("Hour")
local STR_MINUTE = CSTextManagerGetText("Minute")
local STR_SECOND = CSTextManagerGetText("Second")
local S = 60
local H = 3600
local D = 3600 * 24
local W = 3600 * 24 * 7
local M = 3600 * 24 * 30
local PcRechargeEnabled = true
XUiHelper = XUiHelper or {}
XUiHelper.TimeFormatType = {
DEFAULT = 1, -- 默认时间格式大于一天显示天数小于一天显示xx小时xx分
SHOP = 1, -- 商城时间格式
TOWER = 2, -- 爬塔时间格式
TOWER_RANK = 3, -- 爬塔排行消耗时间格式
CHALLENGE = 4, -- 挑战的时间
HOSTEL = 5, -- 宿舍倒计时
DRAW = 6, -- 抽卡倒计时
MAIN = 7, -- 主界面系统时间
PURCHASELB = 8, -- 礼包时间
ONLINE_BOSS = 9, -- 联机boss
ACTIVITY = 10, -- 活动
MAINBATTERY = 11, -- 主界面血清剩余时间
HEADPORTRAIT = 12, -- 头像时间
DAILY_TASK = 13, --每日任务显示X时X分不足一分钟时显示一分钟
GUILDCD = 14, -- 公会冷却倒计时
CHATEMOJITIMER = 15, -- 倒计时(大于一天显示天数,小于一天大于一小时显示小时,小于一小时大于一分钟显示分钟,小于一分钟大于一秒钟显示秒钟)
ACTIVITY_LINEBREAK = 16, --日期会换行(例10\n天)
NieRShow = 17, --尼尔玩法显示剩余时间(汉字替换为英文字符)
STRONGHOLD = 18, --超级据点时间格式
TO_A_MINUTE = 19, --时间精确到分,不足一分钟时显示<1分钟倒计时结束输出0分钟
MOE_WAR = 20, --倒计时(大于一天显示天数,小于一天大于一小时显示小时,小于一小时大于一分钟显示分钟,小于一分钟大于一秒钟显示一分钟)
KillZone = 21, --杀戮无双当剩余时间大于1天时按天显示时间当剩余时间小于1天时按小时显示时间剩余时间少于1小时也显示1小时
RPG_MAKER_GAME = 22, --谜题玩法,只显示天(向上取整)
PASSPORT = 23, --战斗通行证大于1天时按天显示时间当剩余时间小于1天时按小时显示时间剩余时间少于1小时固定显示1小时
RPG_MAKER_GAME_MAIN = 24, --谜题玩法主界面时间格式同活动ACTIVITY一致调整了时间文字大小
AREA_WAR_AREA_UNLOCK = 25, --全服决战区域开放倒计时大于24H显示【xx天后开启】小于24H显示【xx时后开启】没有更小单位
NEW_REGRESSION_ENTRANCE = 26, --新回归活动入口(只显示一个向上取整的时间单位,最大单位:周,最小单位:小时)
NEW_REGRESSION = 27, --新回归活动(只显示一个向上取整的时间单位,最大单位:天,最小单位:小时)
DOOMSDAY = 28, --模拟经营活动时间显示规则:1活动时间剩余>=24 小时 剩余时间精确到【天】,取整显示 2活动时间剩余>24 小时精确到【小时】,取整显示剩余时间小于 1 小时,仍然显示剩余 1 小时
DOOMSDAY_STAGE = 29, --模拟经营关卡时间显示规则:精确到【天】,小于 1 天的,仍然显示 1 天
ESCAPE_ACTIVITY = 30, --大逃杀玩法活动倒计时(大于一天显示天数,小于一天大于一小时显示小时,小于一小时大于一分钟显示分钟,小于一分钟大于一秒钟显示一分钟,返回时间和时间单位两个参数)
ESCAPE_REMAIN_TIME = 31, --大逃杀玩法剩余通关时间显示xx分:xx秒
ACTIVITY_NEW_YEAR_FUBEN = 32, -- 琥虎符福(只显示"x天"最少1天"天"字是黑色)
DOUBLE_TOWER = 33,-- 动作塔防(只显示到分,最少一分钟,忽略秒)
HOUR_MINUTE_SECOND = 34, -- 格式化时间1:20:20/10:20
DAY_HOUR = 35, --大于一天显示【X天X小时】,小于一小时显示【X小时X分X秒】
PIVOT_COMBAT = 36, --独域特攻 大于一小时则按 xx天xx小时 小于一小时 则 xx分xx秒
Multi_Dim = 37, --多维挑战 显示xx:xx:xx,当前大于1天时小时加24
SHOP_REFRESH = 38, -- 商店自动刷新倒计时
MINUTE_SECOND = 39, --只显示分和秒,他转换成分。
PLANET_RUNNING = 40, -- 行星环游记 大于一小时则按 xx天xx小时 小于一小时 则 xx分xx秒
}
XUiHelper.DelayType = {
Second = 1,
Minute = 2,
Hour = 3,
Day = 4
}
--- 时间单位
---@field Second number 秒
---@field Minute number 分
---@field Hour number 时
---@field Day number 天
---@field Week number 周
---@field Mouth number 月
XUiHelper.TimeUnit = {
Second = 1,
Minute = 2,
Hour = 3,
Day = 4,
Week = 5,
Mouth = 6
}
XUiHelper.ClientConfigType = {
String = 1,
Float = 2,
Int = 3,
Bool = 4
}
XUiHelper.TagBgPath = {
Red = CS.XGame.ClientConfig:GetString("UiBagItemRed"),
Yellow = CS.XGame.ClientConfig:GetString("UiBagItemYellow"),
Blue = CS.XGame.ClientConfig:GetString("UiBagItemBlue"),
Green = CS.XGame.ClientConfig:GetString("UiBagItemGreen")
}
function XUiHelper.CreateTemplates(rootUi, pool, datas, ctor, template, parent, onCreate)
for i = 1, #datas do
local data = datas[i]
local item
if i <= #pool then
item = pool[i]
else
local go = CS.UnityEngine.Object.Instantiate(template)
go.transform:SetParent(parent, false)
if rootUi then
item = ctor(rootUi, go)
else
item = ctor(go)
end
pool[i] = item
end
if onCreate then
onCreate(item, data)
end
end
for i = #datas + 1, #pool do
local item = pool[i]
item.GameObject:SetActive(false)
end
end
function XUiHelper.CreateScrollItem(datas, template, parent, cb, scrollstyle)
scrollstyle = scrollstyle or XGlobalVar.ScrollViewScrollDir.ScrollDown
local width, height =
template.gameObject:GetComponent("RectTransform").rect.width,
template.gameObject:GetComponent("RectTransform").rect.height
if scrollstyle == XGlobalVar.ScrollViewScrollDir.ScrollDown then
parent:GetComponent("RectTransform").sizeDelta = CS.UnityEngine.Vector2(0, #datas * height)
elseif scrollstyle == XGlobalVar.ScrollViewScrollDir.ScrollRight then
parent:GetComponent("RectTransform").sizeDelta = CS.UnityEngine.Vector2(#datas * width, 0)
end
for i = 1, #datas do
local obj = CS.UnityEngine.Object.Instantiate(template)
obj.gameObject:SetActive(true)
if scrollstyle == XGlobalVar.ScrollViewScrollDir.ScrollDown then
obj.transform.localPosition = CS.UnityEngine.Vector3(width / 2, -height / 2 - height * (i - 1), 0)
elseif scrollstyle == XGlobalVar.ScrollViewScrollDir.ScrollRight then
obj.transform.localPosition = CS.UnityEngine.Vector3(width * (i - 1), 0, 0)
end
obj.transform.localScale = CS.UnityEngine.Vector3(1, 1, 1)
obj.transform.localEulerAngles = CS.UnityEngine.Vector3(0, 0, 0)
obj.transform:SetParent(parent, false)
cb(obj, datas[i])
end
end
function XUiHelper.TryGetComponent(transform, path, type)
local temp = transform:Find(path)
if temp then
if type then
return temp:GetComponent(type)
else
return temp
end
else
return nil
end
end
---@param rootUi XLuaUi
function XUiHelper.SetQualityIcon(rootUi, imgQuality, quality)
local spriteName = XArrangeConfigs.GeQualityPath(quality)
if rootUi then
rootUi:SetUiSprite(imgQuality, spriteName)
else
imgQuality:SetSprite(spriteName)
end
end
function XUiHelper.GetPanelRoot(ui)
while ui.Parent do
ui = ui.Parent
end
return ui
end
------------时间相关begin------------
--==============================--
--desc: 固定的时间格式
--@second: 总秒数
--@return: 固定的时间格式
-- 时间大于1个月 则返回 X个月
-- 时间大于1周 则返回 X周
-- 时间大于1天 则返回 X天
-- 其余 则返回 XX:XX:XX
--==============================--
function XUiHelper.GetTime(second, timeFormatType)
timeFormatType = timeFormatType and timeFormatType or XUiHelper.TimeFormatType.DEFAULT
local month, weeks, days, hours, minutes, seconds = XUiHelper.GetTimeNumber(second)
if timeFormatType == XUiHelper.TimeFormatType.DEFAULT then
if month >= 1 then
return stringFormat("%d %s", month, STR_MONTH)
end
if weeks >= 1 then
return stringFormat("%d %s", weeks, STR_WEEK)
end
if days >= 1 then
return stringFormat("%d %s", days, STR_DAY)
end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.MAINBATTERY then
if month >= 1 then
return stringFormat("%d%s", month, STR_MONTH)
end
if weeks >= 1 then
return stringFormat("%d%s", weeks, STR_WEEK)
end
if days >= 1 then
return stringFormat("%d%s", days, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
local notZeroMin = minutes > 0 and minutes or 1
return stringFormat("%d%s", notZeroMin, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.ACTIVITY then
local totalDays = mathFloor(second / D)
if totalDays >= 1 then
return stringFormat("%d%s", totalDays, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
if minutes >= 1 then
return stringFormat("%d%s", minutes, STR_MINUTE)
end
return stringFormat("%d%s", seconds, STR_SECOND)
end
if timeFormatType == XUiHelper.TimeFormatType.ACTIVITY_NEW_YEAR_FUBEN then
local totalDays = mathFloor(second / D)
local formatStr = "%d\n<color=#595554FF><size=25>%s</size></color>"
if totalDays >= 1 then
return stringFormat(formatStr, totalDays, STR_DAY)
end
if hours >= 1 then
return stringFormat(formatStr, hours, STR_HOUR)
end
if minutes >= 1 then
return stringFormat(formatStr, minutes, STR_MINUTE)
end
return stringFormat(formatStr, seconds, STR_SECOND)
end
if timeFormatType == XUiHelper.TimeFormatType.ACTIVITY_LINEBREAK then
local totalDays = mathFloor(second / D)
if totalDays >= 1 then
return stringFormat("%d\n%s", totalDays, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d\n%s", hours, STR_HOUR)
end
if minutes >= 1 then
return stringFormat("%d\n%s", minutes, STR_MINUTE)
end
return stringFormat("%d\n%s", seconds, STR_SECOND)
end
if timeFormatType == XUiHelper.TimeFormatType.TOWER then
return stringFormat("%d%s%02d%s%02d%s", days, STR_DAY, hours, STR_HOUR, minutes, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.TOWER_RANK then
return stringFormat("%02d%s%02d%s", minutes, STR_MINUTE, seconds, STR_SECOND)
end
if timeFormatType == XUiHelper.TimeFormatType.DAILY_TASK then
if minutes < 1 and seconds > 0 then
minutes = 1
end
return stringFormat("%02d%s%02d%s", hours, STR_HOUR, minutes, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.CHALLENGE or timeFormatType == XUiHelper.TimeFormatType.HOSTEL then
if month >= 1 then
return stringFormat("%d%s", month, STR_MONTH)
end
if weeks >= 1 then
return stringFormat("%d%s", weeks, STR_WEEK)
end
if days >= 1 then
return stringFormat("%d%s%d%s", days, STR_DAY, hours, STR_HOUR)
end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.DRAW then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
if minutes >= 1 then
return stringFormat("%d%s", minutes, STR_MINUTE)
end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.GUILDCD then
return stringFormat("%01d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.MAIN then
return stringFormat("%02d:%02d", hours, minutes)
end
if timeFormatType == XUiHelper.TimeFormatType.PURCHASELB then
if month >= 1 or weeks >= 1 or days >= 1 then
local sumDas = mathFloor(second / D)
return stringFormat("%d%s", sumDas, STR_DAY)
end
-- if days >= 1 then en1.22需求 一周到一天之前保持与大于一周显示一致
-- return stringFormat("%d%s%d%s", days, STR_DAY, hours, STR_HOUR)
-- end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.ONLINE_BOSS then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
return stringFormat("%02d:%02d", minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.HEADPORTRAIT then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
if minutes < 1 and seconds > 0 then
minutes = 1
end
return stringFormat("%d%s", minutes, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.CHATEMOJITIMER then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
if minutes < 1 and seconds > 0 then
return stringFormat("%d%s", seconds, STR_SECOND)
end
return stringFormat("%d%s", minutes, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.NieRShow then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, "DAY")
end
if hours >= 1 then
return stringFormat("%d%s", hours, "Hour")
end
if minutes < 1 and seconds > 0 then
return stringFormat("%d%s", seconds, "Second")
end
return stringFormat("%d%s", minutes, "Minute")
end
if timeFormatType == XUiHelper.TimeFormatType.STRONGHOLD then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s%d%s", sumDas, STR_DAY, hours, STR_HOUR)
end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.TO_A_MINUTE then
if days >= 1 then
return stringFormat("%d%s%d%s%d%s", days, STR_DAY, hours, STR_HOUR, minutes, STR_MINUTE)
end
if hours >= 1 then
return stringFormat("%d%s%d%s", hours, STR_HOUR, minutes, STR_MINUTE)
end
if minutes < 1 and seconds > 0 then
return stringFormat("<1%s", STR_MINUTE)
end
return stringFormat("%d%s", minutes, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.MOE_WAR then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
if minutes < 1 and seconds > 0 then
minutes = 1
end
return stringFormat("%d%s", minutes, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.KillZone then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
return stringFormat("%d%s", minutes, STR_MINUTE)
end
if timeFormatType == XUiHelper.TimeFormatType.RPG_MAKER_GAME then
local sumDas = mathCeil(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
return stringFormat("%d%s", 0, STR_DAY)
end
if timeFormatType == XUiHelper.TimeFormatType.PASSPORT then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
return stringFormat("%d%s", 1, STR_HOUR)
end
if timeFormatType == XUiHelper.TimeFormatType.NEW_REGRESSION_ENTRANCE then
local week = mathCeil(second / W)
if second >= W then
return stringFormat("%d%s", week, STR_WEEK)
end
local day = mathCeil(second / D)
if second >= D then
return stringFormat("%d%s", day, STR_DAY)
end
local hour = mathMax(1, mathCeil(second / H))
return stringFormat("%d%s", hour, STR_HOUR)
end
if timeFormatType == XUiHelper.TimeFormatType.NEW_REGRESSION then
local day = mathCeil(second / D)
if second >= D then
return stringFormat("%d%s", day, STR_DAY)
end
local hour = mathMax(1, mathCeil(second / H))
return stringFormat("%d%s", hour, STR_HOUR)
end
if timeFormatType == XUiHelper.TimeFormatType.RPG_MAKER_GAME_MAIN then
local totalDays = mathFloor(second / D)
if totalDays >= 1 then
return stringFormat("%d<size=32>%s</size>", totalDays, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d<size=32>%s</size>", hours, STR_HOUR)
end
if minutes >= 1 then
return stringFormat("%d<size=32>%s</size>", minutes, STR_MINUTE)
end
return stringFormat("%d<size=32>%s</size>", seconds, STR_SECOND)
end
if timeFormatType == XUiHelper.TimeFormatType.AREA_WAR_AREA_UNLOCK then
local sumDas = mathCeil(second / D)
if sumDas >= 1 then
return stringFormat("%d%s", sumDas, STR_DAY)
end
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
end
return stringFormat("%d%s", 1, STR_HOUR)
end
if timeFormatType == XUiHelper.TimeFormatType.DOOMSDAY then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return sumDas, STR_DAY
end
if hours >= 1 then
return hours, STR_HOUR
end
return 1, STR_HOUR
end
if timeFormatType == XUiHelper.TimeFormatType.DOOMSDAY_STAGE then
local sumDas = mathFloor(second / D)
return sumDas > 1 and sumDas or 1
end
if timeFormatType == XUiHelper.TimeFormatType.ESCAPE_ACTIVITY then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return sumDas, STR_DAY
end
if hours >= 1 then
return hours, STR_HOUR
end
if minutes < 1 and seconds > 0 then
minutes = 1
end
return minutes, STR_MINUTE
end
if timeFormatType == XUiHelper.TimeFormatType.ESCAPE_REMAIN_TIME then
return string.format("%02d:%02d", minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.DOUBLE_TOWER then
if month >= 1 then
return stringFormat("%d%s", month, STR_MONTH)
end
if weeks >= 1 then
return stringFormat("%d%s", weeks, STR_WEEK)
end
if days >= 1 then
return stringFormat("%d%s", days, STR_DAY)
end
minutes = math.max(minutes, 1)
return stringFormat("%02d:%02d", hours, minutes)
end
if timeFormatType == XUiHelper.TimeFormatType.HOUR_MINUTE_SECOND then
local ret = ""
local hour = math.floor(second / H)
second = second - hour * H
local minute = math.floor(second / S)
second = second - minute * S
local second = math.floor(second % S)
local secondStr
if second < 10 then
secondStr = "0".. second
else
secondStr = second
end
if hour >= 1 then
local minuteStr
if minute < 10 then
minuteStr = "0" .. minute
else
minuteStr = minute
end
ret = string.format("%s:%s:%s", hour, minuteStr, secondStr)
else
if minute >= 1 then
ret = string.format("%s:%s", minute, secondStr)
else
ret = string.format("00:%s", secondStr)
end
end
return ret
end
if timeFormatType == XUiHelper.TimeFormatType.DAY_HOUR then
local sumDas = mathFloor(second / D)
if sumDas >= 1 then
return stringFormat("%d%s%d%s", sumDas, STR_DAY, hours, STR_HOUR)
end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.PIVOT_COMBAT then
local totalDays = mathFloor(second / D)
if totalDays >= 1 then
return stringFormat("%d%s%d%s", totalDays, STR_DAY, hours, STR_HOUR)
else
if hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
elseif minutes >= 1 then
return stringFormat("%d%s%d%s", minutes, STR_MINUTE, seconds, STR_SECOND)
else
return stringFormat("%d%s", seconds, STR_SECOND)
end
end
end
if timeFormatType == XUiHelper.TimeFormatType.Multi_Dim then
if days >= 1 then
hours = hours + 24
end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.SHOP_REFRESH then
if month >= 1 then
return stringFormat("%d%s", month, STR_MONTH)
end
if days >= 1 or weeks >= 1 then
local dayOfWeek = 7
return stringFormat("%d%s", days + weeks * dayOfWeek, STR_DAY)
end
return stringFormat("%02d:%02d:%02d", hours, minutes, seconds)
end
if timeFormatType == XUiHelper.TimeFormatType.MINUTE_SECOND then
local ret = ""
local minute = math.floor(second / S)
second = second - minute * S
local second = math.floor(second % S)
local secondStr
if second < 10 then
secondStr = "0".. second
else
secondStr = second
end
local minuteStr
if minute == 0 then
minuteStr = "00"
elseif minute >= 10 then
minuteStr = minute
else
minuteStr = "0" .. minute
end
ret = string.format("%s:%s", minuteStr, secondStr)
return ret
end
if timeFormatType == XUiHelper.TimeFormatType.PLANET_RUNNING then
local totalDays = mathFloor(second / D)
if totalDays >= 1 then
return stringFormat("%d%s%d%s", totalDays, STR_DAY, hours, STR_HOUR)
elseif hours >= 1 then
return stringFormat("%d%s", hours, STR_HOUR)
elseif minutes >= 1 then
return stringFormat("%d%s", minutes, STR_MINUTE)
else
return stringFormat("%d%s", seconds, STR_SECOND)
end
end
end
function XUiHelper.GetTimeNumber(second)
local month = mathFloor(second / M)
local weeks = mathFloor((second % M) / W)
local days = mathFloor((second % W) / D)
local hours = mathFloor((second % D) / H)
local minutes = mathFloor((second % H) / S)
local seconds = mathFloor(second % S)
return month, weeks, days, hours, minutes, seconds
end
function XUiHelper.GetTimeOfDelay(time, delayTime, delayType) --获取延时后的时间戳
if delayType == XUiHelper.DelayType.Second then
return time + delayTime
elseif delayType == XUiHelper.DelayType.Minute then
return time + delayTime * S
elseif delayType == XUiHelper.DelayType.Hour then
return time + delayTime * H
elseif delayType == XUiHelper.DelayType.Day then
return time + delayTime * D
end
return time + delayTime
end
--背包限时道具时间样式
function XUiHelper.GetBagTimeLimitTimeStrAndBg(second)
local timeStr, bgPath
local weeks = mathFloor(second / W)
local days = mathFloor((second % W) / D)
local hours = mathFloor((second % D) / H)
local minutes = mathFloor((second % H) / S)
if weeks >= 1 then
timeStr = stringFormat("%d%s", weeks, STR_WEEK)
bgPath = XUiHelper.TagBgPath.Green
elseif days >= 1 then
timeStr = stringFormat("%d%s", days, STR_DAY)
bgPath = XUiHelper.TagBgPath.Yellow
elseif hours >= 1 then
timeStr = stringFormat("%d%s", hours, STR_HOUR)
bgPath = XUiHelper.TagBgPath.Red
else
local notZeroMin = minutes > 0 and minutes or 1
timeStr = stringFormat("%d%s", notZeroMin, STR_MINUTE)
bgPath = XUiHelper.TagBgPath.Red
end
return timeStr, bgPath
end
-- length为可选参数为要显示的长度例如3601,1为1小时3601,2为1小时1秒,
function XUiHelper.GetTimeDesc(second, length)
local minute = 60
local hour = 3600
local day = 3600 * 24
if second <= 0 then
return CSTextManagerGetText("IsExpire")
end
if not length then
length = 1
end
local desc = ""
while length > 0 do
if second == 0 then
return desc
end
if second < minute then
local s = mathFloor(second)
desc = desc .. s .. CSTextManagerGetText("Second")
second = 0
else
if second < hour then
local m = mathFloor(second / minute)
desc = desc .. m .. CSTextManagerGetText("Minute")
second = second - m * minute
else
if second < day then
local h = mathFloor(second / hour)
desc = desc .. h .. CSTextManagerGetText("Hour")
second = second - h * hour
else
local d = mathFloor(second / day)
desc = desc .. d .. CSTextManagerGetText("Day")
second = second - d * day
end
end
end
length = length - 1
if length > 0 then
desc = desc .. " "
end
end
return desc
end
--返回X时间开启或X时间结束或已结束
function XUiHelper.GetInTimeDesc(startTime, endTime)
local nowTime = XTime.GetServerNowTimestamp()
local timeStr
if startTime and nowTime < startTime then
timeStr = XUiHelper.GetTime(startTime - nowTime, XUiHelper.TimeFormatType.ACTIVITY)
return CSTextManagerGetText("StartInTime", timeStr)
end
if endTime and nowTime < endTime then
timeStr = XUiHelper.GetTime(endTime - nowTime, XUiHelper.TimeFormatType.ACTIVITY)
return CSTextManagerGetText("EndInTime", timeStr)
end
return CSTextManagerGetText("TimeUp")
end
--==============================--
--desc: 获取最后登录时间描述
--@time: 登录时间
--@return 最后登录时间对应描述
--==============================--
function XUiHelper.CalcLatelyLoginTime(time, nowTime)
nowTime = nowTime or XTime.GetServerNowTimestamp()
local minute = mathFloor((nowTime - time) / 60)
local hourCount = mathFloor(minute / 60)
local dayCount = mathFloor(hourCount / 24)
local monthCount = mathFloor(dayCount / 30)
if monthCount >= 1 then
return monthCount .. CSTextManagerGetText("ToolMonthBefore")
elseif dayCount >= 1 then
return dayCount .. CSTextManagerGetText("ToolDayBrfore")
elseif hourCount >= 1 then
return hourCount .. CSTextManagerGetText("ToolHourBefore")
else
return minute .. CSTextManagerGetText("ToolMinuteBefore")
end
end
--==============================--
--desc: 获取最后登录时间描述
--@time: 登录时间
--@defaultDay: 默认显示的天数
--@return 最后登录时间对应描述
--==============================--
function XUiHelper.CalcLatelyLoginTimeWithDefault(time, defaultDay)
local minute = mathFloor((XTime.GetServerNowTimestamp() - time) / 60)
local hourCount = mathFloor(minute / 60)
local dayCount = mathFloor(hourCount / 24)
if dayCount >= 1 then
if defaultDay and defaultDay < dayCount then
return defaultDay .. CSTextManagerGetText("ToolDayBrfore")
else
return dayCount .. CSTextManagerGetText("ToolDayBrfore")
end
elseif hourCount >= 1 then
return hourCount .. CSTextManagerGetText("ToolHourBefore")
else
return minute .. CSTextManagerGetText("ToolMinuteBefore")
end
end
function XUiHelper.GetRemindTime(time, now)
now = now or XTime.GetServerNowTimestamp()
local remindTime = time - now
if remindTime > 86400 then
local day = mathFloor(remindTime / 86400) + 1
return day .. CSTextManagerGetText("Day")
else
local h = mathFloor(remindTime / 3600)
local m = mathFloor((remindTime - h * 3600) / 60)
local s = mathFloor(remindTime % 60)
return stringFormat("%02d:%02d:%02d", h, m, s)
end
end
--- 获取时间以及单位
---@param second number 秒数
---@param minUnit number 最小单位
---@param maxUnit number 最大单位
---@return table
--------------------------
function XUiHelper.GetTimeAndUnit(second, minUnit, maxUnit)
maxUnit = maxUnit or XUiHelper.TimeUnit.Mouth
minUnit = minUnit or XUiHelper.TimeUnit.Second
local month = mathFloor(second / M)
local weeks = mathFloor(second / W)
local days = mathFloor(second / D)
local hours = mathFloor(second / H)
local minutes = mathFloor(second / S)
local seconds = second
local minUnitStr
local function func(unit, number, str)
if unit == minUnit then
minUnitStr = str
end
if minUnit <= unit and maxUnit >= unit and number >= 1 then
return true, number, str
end
return false, nil, nil
end
local passed, num, unitStr
passed, num, unitStr = func(XUiHelper.TimeUnit.Mouth, month, STR_MONTH)
if passed then
return num, unitStr
end
passed, num, unitStr = func(XUiHelper.TimeUnit.Week, weeks, STR_WEEK)
if passed then
return num, unitStr
end
passed, num, unitStr = func(XUiHelper.TimeUnit.Day, days, STR_DAY)
if passed then
return num, unitStr
end
passed, num, unitStr = func(XUiHelper.TimeUnit.Hour, hours, STR_HOUR)
if passed then
return num, unitStr
end
passed, num, unitStr = func(XUiHelper.TimeUnit.Minute, minutes, STR_MINUTE)
if passed then
return num, unitStr
end
passed, num, unitStr = func(XUiHelper.TimeUnit.Second, seconds, STR_SECOND)
if passed then
return num, unitStr
end
return 1, minUnitStr
end
------------时间相关end------------
--==============================--
--desc: Hex Color 转成 color
--@hexColor: 如:B7C4FFFF或B7C4FF
--@return: color(r, g, b, a)或color(r, g, b)
--==============================--
function XUiHelper.Hexcolor2Color(hexColor)
local str
str = stringSub(hexColor, 1, 2)
local r = tonumber(str, 16) / 255
str = stringSub(hexColor, 3, 4)
local g = tonumber(str, 16) / 255
str = stringSub(hexColor, 5, 6)
local b = tonumber(str, 16) / 255
str = stringSub(hexColor, 7, 8)
local a = string.IsNilOrEmpty(str) and 1 or tonumber(str, 16) / 255
return CS.UnityEngine.Color(r, g, b, a)
end
--------------------------------------
-- 将RGB Color(100, 100, 255) 转换成16进制颜色代码 #6464ff
--------------------------------------
function XUiHelper.Color2Hex(color)
return string.format("#%.2x%.2x%.2x", color.r, color.g, color.b)
end
---@desc 将originColor的RGB转为color的RGB
---@param originColor UnityEngine.Color 初始Color
---@param color UnityEngine.Color 转换成的Color
---@return UnityEngine.Color
function XUiHelper.ConvertColorRGB(originColor, color)
if not color or not originColor then
return CS.UnityEngine.Color.white
end
originColor.r = color.r
originColor.g = color.g
originColor.b = color.b
return originColor
end
------------动画相关begin------------
--==============================--
--desc: 打字机动画
--@txtobj: 文本对象
--@str: 打印的字符串
--@interval: 时间间隔
--@finishcallback: 结束回调
--@return 定时器对象
--==============================--
function XUiHelper.ShowCharByTypeAnimation(txtobj, str, interval, callback, finishcallback)
local chartab = string.CharsConvertToCharTab(str)
local index = 1
local timer
txtobj.text = ""
timer =
XScheduleManager.ScheduleForever(
function()
if index > #chartab then
XScheduleManager.UnSchedule(timer)
if finishcallback then
finishcallback()
end
else
local char = chartab[index]
if callback then
callback(char)
else
txtobj.text = txtobj.text .. char
end
index = index + 1
end
end,
interval
)
return timer
end
-- 如果是子Ui得先定义Parent才能获取到UiAnimation组件。
--弃用
function XUiHelper.PlayAnimation(ui, name, onStart, onEnd)
if onStart then
onStart()
end
if ui.GetType and ui:GetType():ToString() == "UnityEngine.GameObject" then
ui:PlayLegacyAnimation(name, onEnd)
else
ui.GameObject:PlayLegacyAnimation(name, onEnd)
end
end
function XUiHelper.StopAnimation()
end
function XUiHelper.PlayCallback(onStart, onFinish)
return CS.XUiAnimationManager.PlayCallback(onStart, onFinish)
end
-- 播放该节点下的所有粒子特效
function XUiHelper.PlayAllChildParticleSystem(transform)
local allPs = transform:GetComponentsInChildren(typeof(CS.UnityEngine.ParticleSystem), true)
for i = 0, allPs.Length - 1, 1 do
local ps = allPs[i]
ps:Play()
end
end
--==============================--
--desc: 默认不会插入到全局播放列表。
--@duration: 动画时长(s)
--@onRefresh: 刷新动作返回值不为空或true时中断tween
--@onFinish: 结束回调
--@easeMethod: 自定义曲线函数
--@return 定时器
--==============================--
function XUiHelper.Tween(duration, onRefresh, onFinish, easeMethod)
local startTicks = CS.XTimerManager.Ticks
local refresh = function(timer)
local t = (CS.XTimerManager.Ticks - startTicks) / duration / CS.System.TimeSpan.TicksPerSecond
t = mathMin(1, t)
t = mathMax(0, t)
if easeMethod then
t = easeMethod(t)
end
if onRefresh then
local stop = onRefresh(t) or t == 1
if stop then
XScheduleManager.UnSchedule(timer)
if onFinish then
onFinish()
end
return
end
end
end
return XScheduleManager.ScheduleForever(refresh, 0)
end
XUiHelper.EaseType = {
Linear = 1,
Sin = 2,
Increase = 3 --由慢到快
}
function XUiHelper.Evaluate(easeType, t)
if easeType == XUiHelper.EaseType.Linear then
return t
elseif easeType == XUiHelper.EaseType.Sin then
return math.sin(t * math.pi / 2)
elseif easeType == XUiHelper.EaseType.Increase then
t = t * t
t = mathMin(1, t)
t = mathMax(0, t)
return t
end
end
function XUiHelper.DoUiMove(rectTf, tarPos, duration, easeType, cb)
local startPos = rectTf.anchoredPosition3D
easeType = easeType or XUiHelper.EaseType.Linear
local timer =
XUiHelper.Tween(
duration,
function(t)
if not rectTf:Exist() then
return true
end
rectTf.anchoredPosition3D = Vec3Lerp(startPos, tarPos, t)
end,
cb,
function(t)
return XUiHelper.Evaluate(easeType, t)
end
)
return timer
end
function XUiHelper.DoMove(rectTf, tarPos, duration, easeType, cb)
local startPos = rectTf.localPosition
easeType = easeType or XUiHelper.EaseType.Linear
local timer =
XUiHelper.Tween(
duration,
function(t)
if not rectTf:Exist() then
return true
end
rectTf.localPosition = Vec3Lerp(startPos, tarPos, t)
end,
cb,
function(t)
return XUiHelper.Evaluate(easeType, t)
end
)
return timer
end
function XUiHelper.DoWorldMove(rectTf, tarPos, duration, easeType, cb)
local startPos = rectTf.position
easeType = easeType or XUiHelper.EaseType.Linear
local timer =
XUiHelper.Tween(
duration,
function(t)
if not rectTf:Exist() then
return true
end
rectTf.position = Vec3Lerp(startPos, tarPos, t)
end,
cb,
function(t)
return XUiHelper.Evaluate(easeType, t)
end
)
return timer
end
function XUiHelper.DoScale(rectTf, startScale, tarScale, duration, easeType, cb)
easeType = easeType or XUiHelper.EaseType.Linear
local timer =
XUiHelper.Tween(
duration,
function(t)
if not rectTf:Exist() then
return true
end
rectTf.localScale = Vec3Lerp(startScale, tarScale, t)
end,
cb,
function(t)
return XUiHelper.Evaluate(easeType, t)
end
)
return timer
end
function XUiHelper.DoAlpha(canvasGroup, startAlpha, tarAlpha, duration, easeType, cb)
easeType = easeType or XUiHelper.EaseType.Linear
local timer =
XUiHelper.Tween(
duration,
function(t)
if not canvasGroup:Exist() then
return true
end
canvasGroup.alpha = MathLerp(startAlpha, tarAlpha, t)
end,
cb,
function(t)
return XUiHelper.Evaluate(easeType, t)
end
)
return timer
end
------------动画相关end------------
--==============================--
--desc: 计算文本所占宽
--@textObj: 文本对象
--@return 所占宽度
--==============================--
function XUiHelper.CalcTextWidth(textObj)
local tg = textObj.cachedTextGeneratorForLayout
local set = textObj:GetGenerationSettings(CS.UnityEngine.Vector2.zero)
local text = textObj.text
return mathCeil(tg:GetPreferredWidth(text, set) / textObj.pixelsPerUnit)
end
------------首次获得弹窗Begin------------
local FirstGetIdWaitToShowList = {}
local DELAY_POPUP_UI = false
local PopSortFunc = function(a, b)
--角色 > 装备
if a.Type ~= b.Type then
return a.Type == XArrangeConfigs.Types.Weapon
end
if a.Type == XArrangeConfigs.Types.Character then
local aCharacter = XDataCenter.CharacterManager.GetCharacter(a.Id)
local bCharacter = XDataCenter.CharacterManager.GetCharacter(b.Id)
if aCharacter and bCharacter then
--品质
if aCharacter.Quality ~= bCharacter.Quality then
return aCharacter.Quality > bCharacter.Quality
end
--优先级
local priorityA = XCharacterConfigs.GetCharacterPriority(a.Id)
local priorityB = XCharacterConfigs.GetCharacterPriority(b.Id)
if priorityA ~= priorityB then
return priorityA < priorityB
end
end
end
if a.Type == XArrangeConfigs.Types.Weapon then
--品质
local aQuality = XDataCenter.EquipManager.GetEquipQuality(a.Id)
local bQuality = XDataCenter.EquipManager.GetEquipQuality(b.Id)
if aQuality ~= bQuality then
return aQuality > bQuality
end
--优先级
local priorityA = XDataCenter.EquipManager.GetEquipPriority(a.Id)
local priorityB = XDataCenter.EquipManager.GetEquipPriority(b.Id)
if priorityA ~= priorityB then
return priorityA < priorityB
end
end
end
function XUiHelper.PushInFirstGetIdList(id, type)
local beginPopUi = not next(FirstGetIdWaitToShowList)
local data = {Id = id, Type = type}
tableInsert(FirstGetIdWaitToShowList, data)
tableSort(FirstGetIdWaitToShowList, PopSortFunc)
if beginPopUi and not DELAY_POPUP_UI and not XLuaUiManager.IsUiShow("UiFirstGetPopUp") then
XLuaUiManager.Open("UiFirstGetPopUp", FirstGetIdWaitToShowList)
end
end
function XUiHelper.SetDelayPopupFirstGet(isDelay)
DELAY_POPUP_UI = isDelay
end
function XUiHelper.PopupFirstGet()
if next(FirstGetIdWaitToShowList) then
XLuaUiManager.Open("UiFirstGetPopUp", FirstGetIdWaitToShowList)
end
end
------------首次获得弹窗End------------
function XUiHelper.RegisterClickEvent(table, component, handle, clear)
clear = clear and true or true
local func = function(...)
if handle then
handle(table, ...)
end
-- 如果包含信号数据
if type(component) == "table" and component.SignalData then
component.SignalData:EmitSignal("OnPressed", ...)
end
end
if type(component) == "table" and component.__Source then
CsXUiHelper.RegisterClickEvent(component.__Source, func, clear)
else
CsXUiHelper.RegisterClickEvent(component, func, clear)
end
end
function XUiHelper.RegisterHelpButton(btn, helpKey, cb)
XUiHelper.RegisterClickEvent(
nil,
btn,
function()
XUiManager.ShowHelpTip(helpKey, cb)
end
)
end
function XUiHelper.RegisterSliderChangeEvent(table, component, handle, clear)
clear = clear and true or true
local func = function(...)
if handle then
handle(table, ...)
end
end
CsXUiHelper.RegisterSliderChangeEvent(component, func, clear)
end
function XUiHelper.GetToggleVal(val)
if val == XUiToggleState.Off then
return false
elseif val == XUiToggleState.On then
return true
end
end
function XUiHelper.ReplaceWithPlayerName(str, replaceStr)
if not str or not replaceStr then
return str
end
if not stringFind(str, replaceStr) then
return str
end
local playerName = XPlayer.Name
if not playerName then
return str
end
local tmpPlayerName = stringGsub(playerName, "%%", "$")
str = stringGsub(str, replaceStr, tmpPlayerName)
str = stringGsub(str, "%$", "%%")
return str
end
--把大数字按照一定的规范转换成字符串
--规范小于6位不转换大于等于6位转换为w并保留小数点后2位
--比如 600000 返回 60w
function XUiHelper.GetLargeIntNumText(num)
local t = type(num)
if t == "number" then
if num >= 100000 then
local bigNum = num / 1000
if math.floor(bigNum) < bigNum then
return CS.XTextManager.GetText("ShowLargeIntNumText", string.format("%.2f", bigNum))-- 日服W转换为万(日本人能看懂万字)
else
return CS.XTextManager.GetText("ShowLargeIntNumText", string.format("%d", bigNum))
end
else
return tostring(num)
end
end
end
--富文本字符串转普通文本
--@param: <color=#25BF6D>山穷水绝处回眸一遍你</color>
--@return: 山穷水绝处回眸一遍你
function XUiHelper.RichTextToTextString(str)
if not str then
return ""
end
return stringGsub(str, "%b<>", "")
end
--字符串换行符可用化
function XUiHelper.ConvertLineBreakSymbol(str)
if not str then
return ""
end
return stringGsub(str, "\\n", "\n")
end
--策划需求 空格字符转换行
function XUiHelper.ConvertSpaceToLineBreak(str)
if not str then
return ""
end
return stringGsub(str, "%s+", "\n")
end
--读取Text配置并保留换行符
---@return string, number
function XUiHelper.ReadTextWithNewLine(text, ...)
return stringGsub(CSTextManagerGetText(text, ...), "\\n", "\n")
end
---@return string
function XUiHelper.ReadTextWithNewLineWithNotNumber(text, ...)
local result, _ = XUiHelper.ReadTextWithNewLine(text, ...)
return result
end
-- 获取屏幕点击位置到指定transform的位置
function XUiHelper.GetScreenClickPosition(transform, camera)
local screenPoint
local platform = CS.UnityEngine.Application.platform
local Input = CS.UnityEngine.Input
if platform == CS.UnityEngine.RuntimePlatform.WindowsEditor
or platform == CS.UnityEngine.RuntimePlatform.WindowsPlayer
then
screenPoint = CS.UnityEngine.Vector2(CS.UnityEngine.Input.mousePosition.x, CS.UnityEngine.Input.mousePosition.y)
else
-- 避免某些模拟器无法点击问题
screenPoint = Input.touchCount >= 1 and Input.GetTouch(0).position or CS.UnityEngine.Vector2(Input.mousePosition.x, Input.mousePosition.y)
end
local hasValue, v2 =
CS.UnityEngine.RectTransformUtility.ScreenPointToLocalPointInRectangle(transform, screenPoint, camera)
if hasValue then
return CS.UnityEngine.Vector3(v2.x, v2.y, 0)
else
return CS.UnityEngine.Vector3.zero
end
end
function XUiHelper.GetText(key, ...)
return CS.XTextManager.GetText(key, ...)
end
---C#的string解析方法
function XUiHelper.FormatText(str, ...)
return CS.XStringEx.Format(str, ...)
end
---兼容换行符
---@param textComponent UnityEngine.UI.Text
function XUiHelper.SetText2LineBreak(textComponent, str)
textComponent.text = XUiHelper.ConvertLineBreakSymbol(str)
end
function XUiHelper.GetClientConfig(key, configType)
if configType == XUiHelper.ClientConfigType.String then
return CS.XGame.ClientConfig:GetString(key)
elseif configType == XUiHelper.ClientConfigType.Int then
return CS.XGame.ClientConfig:GetInt(key)
elseif configType == XUiHelper.ClientConfigType.Float then
return CS.XGame.ClientConfig:GetFloat(key)
elseif configType == XUiHelper.ClientConfigType.Bool then
return CS.XGame.ClientConfig:GetBool(key)
else
return nil
end
end
--clickFunc重写点击方法
---@return XUiPanelActivityAsset
function XUiHelper.NewPanelActivityAsset(itemIds, panelGo, maxCountDic, clickFunc, canBuyItemIds)
if panelGo == nil then
XLog.Error("XUiHelper.NewPanelActivityAsset(itemIds, panelGo) panelGo为nil")
return
end
local assetActivityPanel = XUiPanelActivityAsset.New(panelGo)
if clickFunc then
assetActivityPanel.OnBtnClick = clickFunc
end
-- 不一一注册的话就无法同时监听到两种黑卡id
for k, id in pairs(itemIds) do
XDataCenter.ItemManager.AddCountUpdateListener(id, function()
assetActivityPanel:Refresh(itemIds, canBuyItemIds, maxCountDic)
end, assetActivityPanel)
end
assetActivityPanel:Refresh(itemIds, canBuyItemIds, maxCountDic)
return assetActivityPanel
end
--===================
--通用返回,主菜单按钮控件
--rootUi : 界面Ui
--panel : TopControl面板
--onBack : 点返回键的处理(可缺省缺省时默认操作为Close)
--onMainUi : 点主菜单的处理(可缺省, 缺省时默认操作为RunMain)
--===================
function XUiHelper.NewPanelTopControl(rootUi, panel, onBack, onMainUi)
local TopControl = require("XUi/XUiCommon/XUiTopControl")
return TopControl.New(rootUi, panel, onBack, onMainUi)
end
function XUiHelper.InitUiClass(obj, ui)
obj.GameObject = ui.gameObject or ui.GameObject
obj.Transform = ui.transform or ui.Transform
XTool.InitUiObject(obj)
end
function XUiHelper.Instantiate(go, parent)
return CS.UnityEngine.Object.Instantiate(go, parent)
end
function XUiHelper.Destroy(go)
if XTool.UObjIsNil(go) then
return
end
CS.UnityEngine.Object.Destroy(go)
end
function XUiHelper.GetFillAmountValue(value, maxValue)
return maxValue == 0 and 0 or value / maxValue
end
--获取排行榜特殊排行1,2,3图标
local RankIcon = {
CS.XGame.ClientConfig:GetString("BabelTowerRankIcon1"),
CS.XGame.ClientConfig:GetString("BabelTowerRankIcon2"),
CS.XGame.ClientConfig:GetString("BabelTowerRankIcon3")
}
function XUiHelper.GetRankIcon(rank)
return RankIcon[rank]
end
--获取排名(百分比)
function XUiHelper.GetRankingPercentage(ranking, totalCount)
--表示还未参与活动
if ranking <= 0 then
return CS.XTextManager.GetText("None")
end
return string.format("%s%%", math.floor((ranking / totalCount) * 100))
end
function XUiHelper.RefreshCustomizedList(container, gridGo, count, handleFunc)
gridGo.gameObject:SetActiveEx(false)
-- 先隐藏所有
local childCount = container.childCount
for i = 0, childCount - 1 do
container:GetChild(i).gameObject:SetActiveEx(false)
end
-- 创建或显示相对应的数量对象
local childrens = {}
for i = 1, count do
local child
if i > childCount then
child = XUiHelper.Instantiate(gridGo, container)
else
child = container:GetChild(i - 1)
end
table.insert(childrens, child)
end
-- 操作放回这里,避免根节点处理后拷贝冲突
for i, child in ipairs(childrens) do
child.gameObject:SetActiveEx(true)
if handleFunc then
handleFunc(i, child)
end
end
end
function XUiHelper.MarkLayoutForRebuild(transform)
XScheduleManager.ScheduleOnce(
function()
CS.UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(transform)
end,
0.1
)
end
--根据传入两点坐标计算 连线在UI中的长度、位置与旋转设置给RectTransform对应的sizeDelta、anchoredPosition、localRotation
---@param positionA UnityEngine.Vector3
---@param positionB UnityEngine.Vector3
function XUiHelper.CalculateLineWithTwoPosition(positionA, positionB, rotationAxis)
local vecOffset = positionB - positionA
local width = vecOffset.magnitude
local position = (positionA + positionB) / 2
local angle = CSQuaternion.Euler(CSVector2.Angle(CSVector2(1, 0), vecOffset) * rotationAxis)
return position, width, angle
end
--背包道具时间(日服)
function XUiHelper.GetBagTimeStrAndBg(second)
local timeStr
local days = mathFloor(second / D)
local hours = mathFloor(second / H)
local minutes = mathFloor((second - hours * H) / S)
if days >= 1 then
timeStr = stringFormat("%d%s", days, STR_DAY)
else
local notZeroMin = minutes > 0 and minutes or 1
timeStr = stringFormat("%d:%d", hours, notZeroMin)
end
return timeStr
end
function XUiHelper.TextHasBubble(textComponent, textContent)
if not textComponent then
XLog.Error("The Function \"TextHasBubble\" Param Must Not Be Nil")
return
end
if not textContent then
XLog.Warning("The Function \"TextHasBubble\" Param (textContent) is Nil, Maybe Cause Problem")
end
textComponent:SetTextEllipsis(textContent) -- 扩展方法,显示不全用省略号表示
local textPointHandler = textComponent.gameObject:GetComponent(typeof(CS.XTextPointHandler))
if XTool.UObjIsNil(textPointHandler) then
textPointHandler = textComponent.gameObject:AddComponent(typeof(CS.XTextPointHandler))
end
textPointHandler:AddTouchBeganListener(function()
if XLuaUiManager.IsUiShow("UiBubbleTip") then return end
local touchData = nil
if CS.UnityEngine.Input.touchCount > 1 then
XLog.Debug("BubbleTip:TouchCount is "..CS.UnityEngine.Input.TouchCount)
touchData = CS.UnityEngine.Input.GetTouch(0)
elseif CS.UnityEngine.Input:GetMouseButtonDown(0) then
touchData = {position = CS.UnityEngine.Vector2(CS.UnityEngine.Input.mousePosition.x, CS.UnityEngine.Input.mousePosition.y)}
end
if not touchData then return end
XLuaUiManager.Open("UiBubbleTip", touchData, textContent or textComponent.text)
end)
textPointHandler:AddTouchEndListener(function()
if XLuaUiManager.IsUiShow("UiBubbleTip") then
XLuaUiManager.Close("UiBubbleTip")
end
end)
textPointHandler:AddTouchCancelListener(function()
if XLuaUiManager.IsUiShow("UiBubbleTip") then
XLuaUiManager.Close("UiBubbleTip")
end
end)
end
function XUiHelper.TextHasBubble(textComponent, textContent)
if not textComponent then
XLog.Error("The Function \"TextHasBubble\" Param Must Not Be Nil")
return
end
if not textContent then
XLog.Warning("The Function \"TextHasBubble\" Param (textContent) is Nil, Maybe Cause Problem")
end
textComponent:SetTextEllipsis(textContent) -- 扩展方法,显示不全用省略号表示
local textPointHandler = textComponent.gameObject:GetComponent(typeof(CS.XTextPointHandler))
if XTool.UObjIsNil(textPointHandler) then
textPointHandler = textComponent.gameObject:AddComponent(typeof(CS.XTextPointHandler))
end
textPointHandler:AddTouchBeganListener(function()
if XLuaUiManager.IsUiShow("UiBubbleTip") then return end
local touchData = nil
if CS.UnityEngine.Input.touchCount > 1 then
touchData = CS.UnityEngine.Input.GetTouch(0)
elseif CS.UnityEngine.Input:GetMouseButtonDown(0) then
touchData = {position = CS.UnityEngine.Vector2(CS.UnityEngine.Input.mousePosition.x, CS.UnityEngine.Input.mousePosition.y)}
end
if not touchData then return end
XLuaUiManager.Open("UiBubbleTip", touchData, textContent or textComponent.text)
end)
textPointHandler:AddTouchEndListener(function()
if XLuaUiManager.IsUiShow("UiBubbleTip") then
XLuaUiManager.Close("UiBubbleTip")
end
end)
textPointHandler:AddTouchCancelListener(function()
if XLuaUiManager.IsUiShow("UiBubbleTip") then
XLuaUiManager.Close("UiBubbleTip")
end
end)
end
--==============================
---@desc text表中读到的\n会被Unity识别为\\n
---@content 转换内容
---@return string
--==============================
function XUiHelper.ReplaceTextNewLine(content)
return string.gsub(content, "\\n", "\n")
end
--下述3个方法都是为了避免反复打开聊天界面
---@desc 打开聊天界面
---@isMain 是否从主界面打开
---@channelType 聊天类型
function XUiHelper.OpenUiChatServeMain(isMain, channelType, channelTypeEx)
local ui = CS.XUiManagerExtension.Find("UiChatServeMain")
if ui then
return
end
XLuaUiManager.Open("UiChatServeMain", isMain, channelType, channelTypeEx)
end
---@desc 关闭聊天界面
function XUiHelper.CloseUiChatServeMain()
XLuaUiManager.Close("UiChatServeMain")
end
---@desc 移除聊天界面
function XUiHelper.RemoveUiChatServeMain()
XLuaUiManager.Remove("UiChatServeMain")
end
--==============================
---@desc 全角空格转为半角空格
---@content 转换内容
---@return string
--==============================
function XUiHelper.ReplaceUnicodeSpace(content)
return string.gsub(content, " ", "\u{00A0}")
end
--==============================
---@desc text表中读到的\n会被Unity识别为\\n
---@content 转换内容
---@return string
--==============================
function XUiHelper.ReplaceTextNewLine(content)
return string.gsub(content, "\\n", "\n")
end
--==============================
---@desc 换行空格转换为全角空格(中文文章中使用)
---@content 实现首行缩进
---@return string
--==============================
function XUiHelper.ReplaceTextIndent(content)
if not content then
return ""
end
return stringGsub(content, " ", "\u{3000}")
end
function XUiHelper.GetStringUTF8Length(str)
local len = #str
local left = len
local cnt = 0
local arr={0,0xc0,0xe0,0xf0,0xf8,0xfc}
while left ~= 0 do
local tmp=string.byte(str,-left)
local i=#arr
while arr[i] do
if tmp>=arr[i] then
left=left-i
break
end
i=i-1
end
cnt=cnt+1
end
return cnt
end
function XUiHelper.DeleteOverlengthString(str, length, addSymbol)
local len = XUiHelper.GetStringUTF8Length(str)
if len > length then
local addStr = not string.IsNilOrEmpty(addSymbol) and addSymbol or ""
str = string.sub(str, 1, length * 3) .. addStr
end
return str
end
--- 移除字符串中最后一个指定符号(可以兼容中文符号)
---@param content string
---@param symbol string
function XUiHelper.RemoveLastSymbol(content, symbol)
local last_symbol = content:sub(-#symbol)
if last_symbol == symbol then
content = content:sub(1, -#symbol - 1)
end
return content
end
--==============================
---@desc 记录一级界面按钮埋点
---@btnIndex 按钮下标
--==============================
function XUiHelper.RecordBuriedSpotTypeLevelOne(btnIndex)
local dict = {}
dict["ui_first_button"] = btnIndex
dict["role_level"] = XPlayer.GetLevel()
CS.XRecord.Record(dict, "200004", "UiOpen")
end
-- fixme临时的时钟设置现在2.1版本处理,后续在下版本优化再删除该方法
-- 记录目前开启了时钟的Ui UiMain/UiSceneTip/UiPhotograph/UiFavorabilityNew
local TimeStopTrans = nil --播放特殊动作时出现的带动画的transform
local TempClockFun = function (trans)
if trans then
TimeStopTrans = trans
end
end
function XUiHelper.SetClockTimeTempFun(Ui)
local panel3D = {}
XTool.InitUiObjectByUi(panel3D, Ui.UiSceneInfo.Transform) -- 将场景的内容和镜头的内容加到1个table里
if not panel3D.Uimc_05ClockAni3 then -- 检测是不是时钟场景
return
end
panel3D.Uimc_05ClockAni.gameObject:SetActiveEx(false)
panel3D.Uimc_05ClockAni2.gameObject:SetActiveEx(false)
panel3D.Uimc_05ClockAni3.gameObject:SetActiveEx(true)
local targetClock = panel3D.Uimc_05ClockAni3
local transH = targetClock:Find("Dummy00/Bone001")
local transM = targetClock:Find("Dummy00/Bone005")
local transS = targetClock:Find("Dummy00/Bone003")
XEventManager.AddEventListener(XEventId.EVENT_ACTION_HIDE_UI, TempClockFun)
local TempV3 = Vector3(0, 0, 0) --提出临时变量,减少内存消耗
local doSync = function ()
local timeStamp = XTime.GetLocalNowTimestamp()
local h = tonumber(XTime.TimestampToGameDateTimeString(timeStamp, "HH"))
local m = tonumber(XTime.TimestampToGameDateTimeString(timeStamp, "mm"))
local s = tonumber(XTime.TimestampToGameDateTimeString(timeStamp, "ss"))
-- 换算为12小时制
h = h > 12 and h - 12 or h
-- 各指针角度
local angleS = (s / 60) * 360
local angleM = (m / 60) * 360 + angleS / 60
local angleH = (h / 12) * 360 + angleM / 12
if not XTool.UObjIsNil(TimeStopTrans) then
local t = TimeStopTrans:GetComponent(typeof(CS.XCustomVFXTimeController))
if t and t.TimeScale <= 0 then
return
end
end
-- H
TempV3.x = transH.localEulerAngles.x
TempV3.y = transH.localEulerAngles.y
TempV3.z = -angleH
transH.localEulerAngles = TempV3
-- M
TempV3.x = transM.localEulerAngles.x
TempV3.y = transM.localEulerAngles.y
TempV3.z = -angleM
transM.localEulerAngles = TempV3
-- S
TempV3.x = transS.localEulerAngles.x
TempV3.y = transS.localEulerAngles.y
TempV3.z = -angleS
transS.localEulerAngles = TempV3
end
doSync()
local timer = XScheduleManager.ScheduleForever(function()
doSync()
end, XScheduleManager.SECOND, 0)
return timer
end
-- 配套时钟停止函数(如果开启了必须在Ui的disable调用)
function XUiHelper.StopClockTimeTempFun(Ui, timer)
XScheduleManager.UnSchedule(timer)
XEventManager.RemoveEventListener(XEventId.EVENT_ACTION_HIDE_UI, TempClockFun)
TimeStopTrans = nil
end
-- 设置场景类型
function XUiHelper.SetSceneType(sceneType)
if not sceneType then
return
end
if sceneType == CS.XSceneType.Dormitory then
XEventManager.DispatchEvent(XEventId.EVENT_SCENE_SET_NONE_STATE)
CsXGameEventManager.Instance:Notify(XEventId.EVENT_SCENE_SET_NONE_STATE)
end
CS.XGlobalIllumination.SetSceneType(sceneType)
end
-- xxxx年x月x日 年月日
function XUiHelper.GetTimeYearMonthDay(time)
time = time or XTime.GetServerNowTimestamp()
-- local format = string.format("yyyy%sM%sd%s", XUiHelper.GetText("Year"), XUiHelper.GetText("Monthly"), XUiHelper.GetText("Diary"))
local format = string.format("yyyy/M/d")
local timeStr = XTime.TimestampToLocalDateTimeString(time, format)
return timeStr
end
-- x月x日 xx:xx 月日时分
function XUiHelper.GetTimeMonthDayHourMinutes(time)
time = time or XTime.GetServerNowTimestamp()
local dt = CS.XDateUtil.GetLocalDateTime(time)
local timeStr=string.format("%d%s%d%s %02d:%02d",dt.Month, XUiHelper.GetText("Monthly"),dt.Day,XUiHelper.GetText("Diary"),dt.Hour,dt.Minute)
return timeStr
end
---设置图片
---@param imgObj UnityEngine.UI.RawImage|UnityEngine.UI.Image
function XUiHelper.GetUiSetIcon(imgObj, iconUrl)
if not string.IsNilOrEmpty(iconUrl) then
if imgObj.sprite then
imgObj:SetSprite(iconUrl)
else
imgObj:SetRawImage(iconUrl)
end
end
end
-- 传入3d的localposition相机和目标渲染到的ui。返回vector2
---@param canvasRect UnityEngine.RectTransform|UnityEngine.Transform
---@param fromObjPos UnityEngine.Vector3
---@param cameraWorld UnityEngine.Camera
function XUiHelper.ObjPosToUguiPos(canvasRect, fromObjPos, cameraWorld)
local screenPoint = cameraWorld:WorldToScreenPoint(fromObjPos)
local screenPoint_v2 = Vector2(screenPoint.x, screenPoint.y)
local hasValue, localPoint = CS.UnityEngine.RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, screenPoint_v2, CS.XUiManager.Instance.UiCamera)
return localPoint
end
-- 根据两个单位向量判断夹角
function XUiHelper.GetAngleByVector3(normalizeV3A, normalizeV3B)
local dotRes = Vector3.Dot(normalizeV3A, normalizeV3B)
local angle = math.acos(dotRes) -- 弧度
angle = math.deg(angle) -- 角度
return angle
end
-- 打开提示 [PC] 当前平台虹卡数量不够, 且其他移动端平台虹卡数量同样不够时 弹出提示
function XUiHelper.OpenPurchaseBuyHongKaCountTips()
if not PcRechargeEnabled and XDataCenter.UiPcManager.IsPc() then
XUiManager.TipText("PcPurchaseBuyHongKaCountTips")
else
XUiManager.TipText("PurchaseBuyHongKaCountTips")
end
end
-- [PC] 当前平台虹卡数量不够, 判断其他平台的虹卡数量是否能够购买, 如果海外拥有PC端虹卡, 应当做其他处理
function XUiHelper.CanBuyInOtherPlatformHongKa(consumeCount)
if not XDataCenter.UiPcManager.IsPc() then
return false
end
local otherCount = XPlayer.GetPcOtherPlatformMoneyCardCount()
if not otherCount or not consumeCount then
return false
end
if otherCount < consumeCount then
return false
end
return true
end
-- [PC] 切换到另一个平台的虹卡, 进行接下来的购买流程 (函数名不同是因为功能进行过修改, 之前是直接切换+购买, 后改为仅切换)
function XUiHelper.BuyInOtherPlatformHongka(closeCallback)
local otherCount = XPlayer.GetPcOtherPlatformMoneyCardCount()
local selectedId = XPlayer.GetPcSelectMoneyCardId()
local platform
if selectedId == 8 then
platform = "IOS"
elseif selectedId == 10 then
platform = "安卓"
end
local content = XUiHelper.GetText("PcPurchaseWithSwitchHongka", platform, otherCount);
XUiManager.DialogTip(XUiHelper.GetText("TipTitle"), content, XUiManager.DialogType.Normal, closeCallback,
function()
XPlayer.ChangePcSelectMoneyCardId()
end, nil, nil)
return true
end
function XUiHelper.GetCountNotEnoughTips(consumeId)
local tips = "";
if not PcRechargeEnabled and XDataCenter.UiPcManager.IsPc() and consumeId == XDataCenter.ItemManager.ItemId.HongKa then
tips = XUiHelper.GetText("PcPurchaseBuyHongKaCountTips");
else
local name = XDataCenter.ItemManager.GetItemName(consumeId) or ""
tips = XUiHelper.GetText("PurchaseBuyKaCountTips", name)
end
return tips
end
--由于动画未播放完毕就被setActive(false),导致透明度错误
function XUiHelper.ResetBtnAlpha(button, path)
path = path or "Normal/ImgNormal"
local image = XUiHelper.TryGetComponent(button.transform, path, "Image")
local color = image.color
if color.a ~= 1 then
color.a = 1
image.color = color
end
end
function XUiHelper.OpenMonthlyCardEn()
local items = XDataCenter.PurchaseManager.GetYKTabPurchasePackages()
local cardAData = nil
local cardCData = nil
local cardABoughtFull = false
local cardCBoughtFull = false
for _, item in pairs(items) do
if item.Data.Id == 83028 then
cardAData = item
cardABoughtFull = cardAData:GetCurrentBuyTime() == cardAData:GetBuyLimitTime()
elseif item.Data.Id == 90032 then
cardCData = item
cardCBoughtFull = cardCData:GetCurrentBuyTime() == cardCData:GetBuyLimitTime()
end
end
if not cardAData or not cardCData then
XLog.Error("获取月卡数据失败")
return
end
if cardABoughtFull or cardCBoughtFull then
XUiManager.TipMsg(CS.XTextManager.GetText("PurchaseYKIsOnBuyLimt"))
return
end
XLuaUiManager.Open("UiMonthlyCardEn", cardAData, cardCData)
end