Files
StellaSora_DataLua/lua/gamecore/ui/basectrl.lua
T
SL1900 1714dcc21d Hotfix - 1.4.0.74
EN: 1.4.0.74
CN: 1.4.0.75
JP: 1.4.0.78
KR: 1.4.0.81
2025-12-26 17:30:00 +09:00

909 lines
32 KiB
Lua
Raw 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 ConfigData = require("GameCore.Data.ConfigData")
local TimerManager = require("GameCore.Timer.TimerManager")
local GameResourceLoader = require("Game.Common.Resource.GameResourceLoader")
local ResType = GameResourceLoader.ResType
local AdventureModuleHelper = CS.AdventureModuleHelper
local BaseCtrl = class("BaseCtrl")
local sRootPath = Settings.AB_ROOT_PATH
local bDebugLog = false
local typeof = typeof
function BaseCtrl:ctor(goPrefabInstance, objPanel)
self._panel = objPanel
self._tbTimer = {}
self._mapPrefab = {}
self._mapLoadAssets = {}
self._mapHandler = {}
self._mapNode = {}
self:ParsePrefab(goPrefabInstance)
if type(self.Awake) == "function" then
self:Awake()
end
self._autoRemoveUnusedTimer = nil
end
function BaseCtrl:ParsePrefab(goPrefabInstance)
if goPrefabInstance ~= nil and goPrefabInstance:IsNull() == false then
self.gameObject = goPrefabInstance
end
self:_ParseNode(self._mapNodeConfig)
end
function BaseCtrl:_PreExit(callback, bPlayFadeOut)
self:_UnbindComponentCallback(self._mapNodeConfig)
self:_UnbindEventCallback(self._mapEventConfig)
self:_RemoveAllTimer()
if type(self.OnPreExit) == "function" then
self:OnPreExit()
end
local func_DoCallback = function()
if type(callback) == "function" then
callback()
end
end
if bPlayFadeOut == true and type(self.FadeOut) == "function" then
local nDelayTime = self:FadeOut()
if type(nDelayTime) == "number" and 0 < nDelayTime then
local func_timer = function(timer)
func_DoCallback()
end
TimerManager.Add(1, nDelayTime, self, func_timer, true, true)
else
func_DoCallback()
end
else
func_DoCallback()
end
end
function BaseCtrl:_Exit()
if type(self.OnDisable) == "function" then
self:OnDisable()
end
if type(self._mapNode) == "table" then
for sKey, obj in pairs(self._mapNode) do
if type(obj) ~= "table" then
self._mapNode[sKey] = 0
elseif type(obj.__cname) == "string" then
else
for i, _obj in ipairs(obj) do
if type(_obj) ~= "table" then
self._mapNode[sKey][i] = 0
else
end
end
end
end
end
self:_DebugLogDataCount("OnDisable")
end
function BaseCtrl:_Enter(bPlayFadeIn)
self:_BindComponentCallback(self._mapNodeConfig)
self:_BindEventCallback(self._mapEventConfig)
self:_RegisterRedDot()
if type(self.OnEnable) == "function" then
self:OnEnable()
end
if type(self.FadeIn) == "function" then
self:FadeIn(bPlayFadeIn)
self._panel._nFadeInType = self._panel._nFADEINTYPE
end
self:_DebugLogDataCount("OnEnable")
end
function BaseCtrl:_Destroy()
if type(self.OnDestroy) == "function" then
self:OnDestroy()
end
for k, v in pairs(self._mapPrefab) do
self:DestroyPrefabInstance(k)
end
for k, v in pairs(self._mapLoadAssets) do
self:UnLoadAsset(k)
end
self._panel = nil
self._tbTimer = nil
self._mapPrefab = nil
self._mapLoadAssets = nil
self._mapHandler = nil
self._mapNode = nil
end
function BaseCtrl:_Release()
if self.gameObject ~= nil and self.gameObject:IsNull() == false and type(self.OnRelease) == "function" then
self:OnRelease()
end
end
function BaseCtrl:_ParseNode(mapNodeConfig)
if self.gameObject ~= nil and type(mapNodeConfig) == "table" then
local trPrefabRoot = self.gameObject.transform
local mapNode = {}
local function func_MarkAllNode(trRoot)
local nChildCount = trRoot.childCount - 1
for i = 0, nChildCount do
local trChild = trRoot:GetChild(i)
mapNode[trChild.name] = trChild.gameObject
if trChild.childCount > 0 then
func_MarkAllNode(trChild)
end
end
end
func_MarkAllNode(trPrefabRoot)
for sKey, mapConfig in pairs(mapNodeConfig) do
local sNodeName = mapConfig.sNodeName
local nCount = mapConfig.nCount
local sComponentName = mapConfig.sComponentName
local sCtrlName = mapConfig.sCtrlName
local sLanguageId = mapConfig.sLanguageId
if type(sNodeName) ~= "string" then
sNodeName = tostring(sKey)
end
local tbNodeName = {}
if type(nCount) == "number" then
if type(self._mapNode[sKey]) ~= "table" then
self._mapNode[sKey] = {}
end
for i = 1, nCount do
table.insert(tbNodeName, sNodeName .. tostring(i))
end
else
table.insert(tbNodeName, sNodeName)
end
for nIndex, sName in ipairs(tbNodeName) do
local bComponentFound = true
local objNode
local goNode = mapNode[sName]
if goNode ~= nil then
if type(sCtrlName) == "string" then
local objCtrl
local nGoInstanceId = goNode:GetInstanceID()
for _nObjCtrlIdx, _objCtrl in ipairs(self._panel._tbObjChildCtrl) do
if _objCtrl._nGoInstanceId == nGoInstanceId then
objCtrl = _objCtrl
break
end
end
if objCtrl == nil then
local luaClass = require(sCtrlName)
objCtrl = luaClass.new(goNode, self._panel)
objCtrl._nGoInstanceId = nGoInstanceId
table.insert(self._panel._tbObjChildCtrl, objCtrl)
end
objCtrl:ParsePrefab(goNode)
objNode = objCtrl
else
if sComponentName == nil then
sComponentName = "GameObject"
end
if sComponentName == "GameObject" then
objNode = goNode
elseif sComponentName == "Transform" then
objNode = goNode.transform
else
local _sComponentName = sComponentName
if sComponentName == "InputField_onEndEdit" then
_sComponentName = "InputField"
end
bComponentFound, objNode = goNode:GetNodeComponent(_sComponentName)
if objNode ~= nil and type(sLanguageId) == "string" then
if _sComponentName == "Text" then
if ConfigTable.GetUIText(sLanguageId) then
NovaAPI.SetText(objNode, ConfigTable.GetUIText(sLanguageId))
else
printError("UIText缺失配置:" .. sLanguageId)
end
elseif _sComponentName == "TMP_Text" then
if ConfigTable.GetUIText(sLanguageId) then
NovaAPI.SetTMPText(objNode, ConfigTable.GetUIText(sLanguageId))
else
printError("UIText缺失配置:" .. sLanguageId)
end
end
end
end
end
if bComponentFound == true and objNode ~= nil then
if type(nCount) == "number" then
self._mapNode[sKey][nIndex] = objNode
else
self._mapNode[sKey] = objNode
end
else
printError("节点找到了但组件没找到,节点名:" .. sName .. ",组件名:" .. sComponentName .. "panel id" .. tostring(table.keyof(PanelId, self._panel._nPanelId)))
end
else
printError("界面预设体中配置的节点没找到,预设体名字:" .. trPrefabRoot.name .. ",节点名字:" .. sName)
end
end
end
end
end
function BaseCtrl:_BindComponentCallback(mapNodeConfig)
if type(mapNodeConfig) ~= "table" then
return
end
local func_DoBind = function(objComp, sCompName, cb, sNodeKey, nIndex)
local sHandlerKey = sNodeKey
if type(nIndex) == "number" then
sHandlerKey = sNodeKey .. tostring(nIndex)
end
local func_Handler = function(...)
local ui_func = ui_handler(self, cb, objComp, nIndex)
ui_func(...)
EventManager.Hit(EventId.UIOperate)
end
if sCompName == "Button" then
objComp.onClick:AddListener(func_Handler)
elseif sCompName == "ButtonEx" then
objComp.onClick:AddListener(func_Handler)
elseif sCompName == "UIButton" then
objComp.onClick:AddListener(func_Handler)
elseif sCompName == "NaviButton" then
objComp.onClick:AddListener(func_Handler)
elseif sCompName == "TMPHyperLink" then
objComp.onClick:AddListener(func_Handler)
elseif sCompName == "Toggle" then
NovaAPI.AddToggleListener(objComp, func_Handler)
elseif sCompName == "UIToggle" then
NovaAPI.AddUIToggleListener(objComp, func_Handler)
elseif sCompName == "ScrollRect" then
NovaAPI.AddScrollRectListener(objComp, func_Handler)
elseif sCompName == "Slider" then
NovaAPI.AddSliderListener(objComp, func_Handler)
elseif sCompName == "LoopScrollView" then
objComp.onValueChanged:AddListener(func_Handler)
elseif sCompName == "InputField" then
NovaAPI.AddIPValueChangedListener(objComp, func_Handler)
elseif sCompName == "InputField_onEndEdit" then
objComp.onEndEdit:AddListener(func_Handler)
elseif sCompName == "TMP_Dropdown" then
objComp.onValueChanged:AddListener(func_Handler)
elseif sCompName == "Dropdown" then
NovaAPI.AddDropDownListener(objComp, func_Handler)
elseif sCompName == "TMP_InputField" then
objComp.onValueChanged:AddListener(func_Handler)
elseif sCompName == "LoopScrollSnap" then
objComp.onGridSelect:AddListener(func_Handler)
elseif sCompName == "UIDrag" then
objComp.onDragEvent:AddListener(func_Handler)
else
if sCompName == "UIZoom" then
objComp.onZoom:AddListener(func_Handler)
else
end
end
if type(func_Handler) == "function" then
self._mapHandler[sHandlerKey] = func_Handler
end
end
for sKey, mapConfig in pairs(mapNodeConfig) do
local sCallback = mapConfig.callback
local sComponentName = mapConfig.sComponentName
local nCount = mapConfig.nCount
if type(sCallback) == "string" and type(sComponentName) == "string" then
local funcCallback = self[sCallback]
if type(funcCallback) == "function" then
if type(self._mapNode[sKey]) == "table" and type(nCount) == "number" then
for i = 1, nCount do
func_DoBind(self._mapNode[sKey][i], sComponentName, funcCallback, sKey, i)
end
else
func_DoBind(self._mapNode[sKey], sComponentName, funcCallback, sKey)
end
else
printError("没有找到组件的回调函数,节点名字:" .. sKey .. ",回调函数名字:" .. sCallback)
end
end
end
end
function BaseCtrl:_UnbindComponentCallback(mapNodeConfig)
if type(mapNodeConfig) ~= "table" then
return
end
local func_DoUnbind = function(objComp, sCompName, sNodeKey, nIndex)
local sHandlerKey = sNodeKey
if type(nIndex) == "number" then
sHandlerKey = sNodeKey .. tostring(nIndex)
end
local func_Handler = self._mapHandler[sHandlerKey]
if objComp ~= nil and func_Handler ~= nil then
if sCompName == "Button" then
objComp.onClick:RemoveListener(func_Handler)
elseif sCompName == "ButtonEx" then
objComp.onClick:RemoveListener(func_Handler)
elseif sCompName == "UIButton" then
objComp.onClick:RemoveListener(func_Handler)
elseif sCompName == "NaviButton" then
objComp.onClick:RemoveListener(func_Handler)
elseif sCompName == "TMPHyperLink" then
objComp.onClick:RemoveListener(func_Handler)
elseif sCompName == "Toggle" then
NovaAPI.RemoveToggleListener(objComp, func_Handler)
elseif sCompName == "UIToggle" then
NovaAPI.RemoveUIToggleListener(objComp, func_Handler)
elseif sCompName == "ScrollRect" then
NovaAPI.RemoveScrollRectListener(objComp, func_Handler)
elseif sCompName == "Slider" then
NovaAPI.RemoveSliderListener(objComp, func_Handler)
elseif sCompName == "LoopScrollView" then
objComp.onValueChanged:RemoveListener(func_Handler)
elseif sCompName == "InputField" then
NovaAPI.RemoveIPValueChangedListener(objComp, func_Handler)
elseif sCompName == "InputField_onEndEdit" then
objComp.onEndEdit:RemoveListener(func_Handler)
elseif sCompName == "TMP_Dropdown" then
objComp.onValueChanged:RemoveListener(func_Handler)
elseif sCompName == "Dropdown" then
NovaAPI.RemoveDropDownListener(objComp, func_Handler)
elseif sCompName == "TMP_InputField" then
objComp.onValueChanged:RemoveListener(func_Handler)
elseif sCompName == "LoopScrollSnap" then
objComp.onGridSelect:RemoveListener(func_Handler)
elseif sCompName == "UIDrag" then
objComp.onDragEvent:RemoveListener(func_Handler)
elseif sCompName == "UIZoom" then
objComp.onZoom:RemoveListener(func_Handler)
end
end
self._mapHandler[sHandlerKey] = nil
func_Handler = nil
end
for sKey, mapConfig in pairs(mapNodeConfig) do
local sCallback = mapConfig.callback
local sComponentName = mapConfig.sComponentName
local nCount = mapConfig.nCount
if type(sCallback) == "string" and type(sComponentName) == "string" then
local funcCallback = self[sCallback]
if type(funcCallback) == "function" then
if type(self._mapNode[sKey]) == "table" and type(nCount) == "number" then
for i = 1, nCount do
func_DoUnbind(self._mapNode[sKey][i], sComponentName, sKey, i)
end
else
func_DoUnbind(self._mapNode[sKey], sComponentName, sKey)
end
else
printError("没有找到组件的回调函数,节点名字:" .. sKey .. ",回调函数名字:" .. sCallback)
end
end
end
end
function BaseCtrl:_BindEventCallback(mapEventConfig)
if type(mapEventConfig) ~= "table" then
return
end
for nEventId, sCallbackName in pairs(mapEventConfig) do
local callback = self[sCallbackName]
if type(callback) == "function" then
EventManager.Add(nEventId, self, callback)
end
end
end
function BaseCtrl:_UnbindEventCallback(mapEventConfig)
if type(mapEventConfig) ~= "table" then
return
end
for nEventId, sCallbackName in pairs(mapEventConfig) do
local callback = self[sCallbackName]
if type(callback) == "function" then
EventManager.Remove(nEventId, self, callback)
end
end
end
function BaseCtrl:_RemoveAllTimer()
local n = #self._tbTimer
for i = n, 1, -1 do
TimerManager.Remove(self._tbTimer[i], false)
table.remove(self._tbTimer, i)
end
if table.nums(self._tbTimer) > 0 then
self._tbTimer = {}
end
if self._autoRemoveUnusedTimer ~= nil then
self._autoRemoveUnusedTimer:Cancel()
self._autoRemoveUnusedTimer = nil
end
end
function BaseCtrl:_DebugLogDataCount(sTitle)
if bDebugLog == false then
return
end
local sCtrlName = self.__cname
local sGoName = self.gameObject.name
local nTimerCnt = table.nums(self._tbTimer)
local nPrefabInsCnt = table.nums(self._mapPrefab)
local nHandlerCnt = table.nums(self._mapHandler)
local nNodeCnt = table.nums(self._mapNode)
local sDebugLog = string.format("[%s.%s] 预设体:%s,计时器数量:%d,自理预设体实例数量:%d,回调数量:%d,节点数量:%d。", sCtrlName, sTitle, sGoName, nTimerCnt, nPrefabInsCnt, nHandlerCnt, nNodeCnt)
printLog(sDebugLog)
end
function BaseCtrl:_RegisterRedDot()
if nil ~= self._mapRedDotConfig then
for key, cfg in pairs(self._mapRedDotConfig) do
local sNodeName = cfg.sNodeName
local nNodeIndex = cfg.nNodeIndex
local objNode
if nil == nNodeIndex then
objNode = self._mapNode[sNodeName]
elseif nil ~= self._mapNode[sNodeName] then
objNode = self._mapNode[sNodeName][nNodeIndex]
end
if nil == objNode then
printError(string.format("绑定红点失败!!! 找不到红点节点.key = %s, nodeName = %s", key, sNodeName))
else
RedDotManager.RegisterNode(key, cfg.param, objNode.gameObject)
end
end
end
end
function BaseCtrl:GetPanelId()
return self._panel._nPanelId
end
function BaseCtrl:GetPanelParam()
return self._panel:GetPanelParam()
end
local bActive_AutoFit = true
function BaseCtrl:GetAtlasSprite(sAtlasPath, sSpriteName)
if string.find(sAtlasPath, "/CommonEx/") ~= nil or string.find(sAtlasPath, "/Common/") ~= nil then
printError("新版UI在换过图集做法后,从图集中取Sprite时不应出现/CommonEx/目录 或 /Common/ 目录。" .. sAtlasPath .. "," .. sSpriteName)
printError("panel id:" .. self._panel._nPanelId .. "ctrl name:" .. self.__cname)
return nil
end
local sFullPath = string.format("%sUI/CommonEx/atlas_png/%s/%s.png", sRootPath, sAtlasPath, sSpriteName)
return GameResourceLoader.LoadAsset(ResType.Any, sFullPath, typeof(Sprite))
end
function BaseCtrl:GetPngSprite(sPath, sSurfix, imgObj)
if type(sPath) == "number" then
printError("调用接口处需更新,panel id:" .. self._panel._nPanelId .. "ctrl name:" .. self.__cname)
return nil
end
if type(sPath) == "string" and sPath ~= "" and type(sSurfix) == "string" and sSurfix ~= "" then
if bActive_AutoFit == true then
sPath = self:_AutoFitIcon(imgObj, sPath, sSurfix)
else
sPath = sPath .. sSurfix
end
end
if string.find(sPath, "Icon/") == nil and string.find(sPath, "Image/") == nil and string.find(sPath, "ImageAvg/") == nil and string.find(sPath, "big_sprites/") == nil then
printError("配置表中 Icon 资源字段内容填写错误,应填路径,如:Icon/Item/item_1panel id:" .. self._panel._nPanelId .. "ctrl name:" .. self.__cname)
return nil
else
local sp = GameResourceLoader.LoadAsset(ResType.Any, sRootPath .. sPath .. ".png", typeof(Sprite))
if sp == nil then
printError(string.format("未找到 icon 资源:%spanel id%sctrl name%s", sPath, tostring(self._panel._nPanelId), tostring(self.__cname)))
end
return sp
end
end
function BaseCtrl:GetSprite_FrameColor(nRarity, sFrameType, bBigSprites)
local sPngName = sFrameType .. AllEnum.FrameColor_New[nRarity]
if bBigSprites then
return self:GetPngSprite("UI/big_sprites/" .. sPngName)
else
return self:GetAtlasSprite("12_rare", sPngName)
end
end
function BaseCtrl:GetSprite_Coin(nCoinItemId)
local mapItem = ConfigTable.GetData_Item(nCoinItemId)
if mapItem == nil then
return nil
elseif mapItem.Icon2 == nil or mapItem.Icon2 == "" then
return nil
else
return self:GetPngSprite(mapItem.Icon2)
end
end
function BaseCtrl:GetAvgCharHeadIcon(sSpeakerId, sFace)
if sFace == nil then
sFace = "002"
end
if sSpeakerId == nil or sSpeakerId == "" or sSpeakerId == "avg0_1" or sSpeakerId == "0" then
sSpeakerId = AdjustMainRoleAvgCharId()
end
local sIconPath = string.format("Icon/AvgHead/%s/%s_%s", sSpeakerId, sSpeakerId, sFace)
return self:GetPngSprite(sIconPath)
end
function BaseCtrl:SetSprite(imgObj, sPath)
local sFullPath = sRootPath .. sPath .. ".png"
local bSuc = NovaAPI.SetImageSprite(imgObj, sFullPath)
if not bSuc then
traceback(string.format("Sprite设置失败:%spanel id%sctrl name%s", sFullPath, tostring(self._panel._nPanelId), tostring(self.__cname)))
end
return bSuc
end
function BaseCtrl:SetAtlasSprite(imgObj, sAtlasPath, sSpriteName)
if string.find(sAtlasPath, "/CommonEx/") ~= nil or string.find(sAtlasPath, "/Common/") ~= nil then
printError("新版UI在换过图集做法后,从图集中取Sprite时不应出现/CommonEx/目录 或 /Common/ 目录。" .. sAtlasPath .. "," .. sSpriteName)
printError("panel id:" .. self._panel._nPanelId .. "ctrl name:" .. self.__cname)
return false
end
local sFullPath = string.format("%sUI/CommonEx/atlas_png/%s/%s.png", sRootPath, sAtlasPath, sSpriteName)
local bSuc = NovaAPI.SetImageSprite(imgObj, sFullPath)
if not bSuc then
traceback(string.format("icon设置失败:%spanel id%sctrl name%s", sFullPath, tostring(self._panel._nPanelId), tostring(self.__cname)))
end
return bSuc
end
function BaseCtrl:SetActivityAtlasSprite(imgObj, sActivityPath, sSpriteName)
local sFullPath = string.format("%sUI_Activity/%s/SpriteAtlas/%s.png", sRootPath, sActivityPath, sSpriteName)
local bSuc = NovaAPI.SetImageSprite(imgObj, sFullPath)
if not bSuc then
traceback(string.format("icon设置失败:%spanel id%sctrl name%s", sFullPath, tostring(self._panel._nPanelId), tostring(self.__cname)))
end
return bSuc
end
function BaseCtrl:SetActivityAtlasSprite_New(imgObj, sActivityPath, sSpriteName)
local sFullPath = string.format("%sUI_Activity/%s/%s.png", sRootPath, sActivityPath, sSpriteName)
local bSuc = NovaAPI.SetImageSprite(imgObj, sFullPath)
if not bSuc then
traceback(string.format("icon设置失败:%spanel id%sctrl name%s", sFullPath, tostring(self._panel._nPanelId), tostring(self.__cname)))
end
return bSuc
end
function BaseCtrl:_AutoFitIcon(imgObj, sPath, sSurfix)
local mapAutoFix = AllEnum.CharHeadIconSurfixAutoFit[sSurfix]
if mapAutoFix == nil then
return sPath .. sSurfix
end
local nGlobalScale = 0
local v3GlobalScale = imgObj.transform.lossyScale
if v3GlobalScale.x < v3GlobalScale.y then
nGlobalScale = v3GlobalScale.x
else
nGlobalScale = v3GlobalScale.y
end
nGlobalScale = nGlobalScale / Settings.CANVAS_SCALE
if nGlobalScale <= 0 then
nGlobalScale = 1
end
local rectTransform = imgObj.gameObject:GetComponent("RectTransform")
local nTargetWidth = rectTransform.rect.width * nGlobalScale
local nTargetHeight = rectTransform.rect.height * nGlobalScale
local sAutoFit, nRange
for k, v in pairs(mapAutoFix) do
local nMultiple_W = math.abs(nTargetWidth - v.w) / v.w
local nMultiple_H = math.abs(nTargetHeight - v.h) / v.h
local nMultiple = nMultiple_W >= nMultiple_H and nMultiple_W or nMultiple_H
if nRange == nil then
nRange = nMultiple
sAutoFit = k
elseif nMultiple < nRange then
nRange = nMultiple
sAutoFit = k
end
end
if sAutoFit == nil then
if NovaAPI.IsEditorPlatform() == true then
printLog("【抽卡角色头像 icon 自适应】未自适应")
end
return sPath .. sSurfix
else
if NovaAPI.IsEditorPlatform() == true then
printLog(string.format("【抽卡角色头像 icon 自适应】全局缩放:x%f,y%f,最终取%f,应用处算上全局缩放后的尺寸:w%f,h%f,自适应至后缀:%s,宽%f,高%f。", v3GlobalScale.x, v3GlobalScale.y, nGlobalScale, nTargetWidth, nTargetHeight, sAutoFit, mapAutoFix[sAutoFit].w, mapAutoFix[sAutoFit].h))
end
local _sPath = sPath .. sAutoFit
local bExist = GameResourceLoader.ExistsAsset(sRootPath .. _sPath .. ".png")
if bExist == false then
if NovaAPI.IsEditorPlatform() == true then
printError(string.format("抽卡角色头像 icon 自适应失败,资源缺失。%s 将 %s 自适应调整为 %s", sPath, sSurfix, sAutoFit))
end
_sPath = sPath .. sSurfix
NovaAPI.SetImageColor(imgObj, Color.cyan)
end
return _sPath
end
end
function BaseCtrl:SetPngSprite(imgObj, sPath, sSurfix)
if type(sPath) == "number" then
traceback("调用接口处需更新,panel id:" .. self._panel._nPanelId .. "ctrl name:" .. self.__cname)
NovaAPI.SetImageSpriteAsset(imgObj, nil)
return false
end
if type(sPath) == "string" and sPath ~= "" and type(sSurfix) == "string" and sSurfix ~= "" then
if bActive_AutoFit == true then
sPath = self:_AutoFitIcon(imgObj, sPath, sSurfix)
else
sPath = sPath .. sSurfix
end
end
if string.find(sPath, "Icon/") == nil and string.find(sPath, "Image/") == nil and string.find(sPath, "ImageAvg/") == nil and string.find(sPath, "big_sprites/") == nil and string.find(sPath, "Disc/") == nil and string.find(sPath, "Play_") == nil and string.find(sPath, "UI_Activity") == nil then
traceback("配置表中 Icon 资源字段内容填写错误,应填路径,如:Icon/Item/item_1panel id:" .. self._panel._nPanelId .. "ctrl name:" .. self.__cname)
NovaAPI.SetImageSpriteAsset(imgObj, nil)
return false
else
local sFullPath = sRootPath .. sPath .. ".png"
local bSuc = NovaAPI.SetImageSprite(imgObj, sFullPath)
if not bSuc then
traceback(string.format("icon设置失败:%spanel id%sctrl name%s", sFullPath, tostring(self._panel._nPanelId), tostring(self.__cname)))
end
return bSuc
end
end
function BaseCtrl:SetSprite_FrameColor(imgObj, nRarity, sFrameType, bBigSprites)
local sPngName = sFrameType .. AllEnum.FrameColor_New[nRarity]
if bBigSprites then
return self:SetPngSprite(imgObj, "UI/big_sprites/" .. sPngName)
else
return self:SetAtlasSprite(imgObj, "12_rare", sPngName)
end
end
function BaseCtrl:SetSprite_Coin(imgObj, nCoinItemId)
local mapItem = ConfigTable.GetData_Item(nCoinItemId)
if mapItem == nil then
return false
elseif mapItem.Icon2 == nil or mapItem.Icon2 == "" then
return false
else
return self:SetPngSprite(imgObj, mapItem.Icon2)
end
end
function BaseCtrl:SetAvgCharHeadIcon(imgObj, sSpeakerId, sFace)
if sFace == nil then
sFace = "002"
end
if sSpeakerId == nil or sSpeakerId == "" or sSpeakerId == "avg0_1" or sSpeakerId == "0" then
sSpeakerId = AdjustMainRoleAvgCharId()
end
local sIconPath = string.format("Icon/AvgHead/%s/%s_%s", sSpeakerId, sSpeakerId, sFace)
return self:SetPngSprite(imgObj, sIconPath)
end
function BaseCtrl:GetAvgStageEffect(sName, sType)
if sName == nil then
return nil
end
local sFullPath = string.format("%sImageAvg/AvgStageEffect/%s.png", sRootPath, sName)
return GameResourceLoader.LoadAsset(ResType.Any, sFullPath, typeof(Texture))
end
function BaseCtrl:GetAvgPortrait(sAvgCharId, sPose, sFace)
local sPathBody = string.format("%sActor2D/CharacterAvg/%s/atlas_png/%s/%s_%s_001.png", sRootPath, sAvgCharId, sPose, sAvgCharId, sPose)
local sPathFace = string.format("%sActor2D/CharacterAvg/%s/atlas_png/%s/%s_%s_%s.png", sRootPath, sAvgCharId, sPose, sAvgCharId, sPose, sFace)
local sPathBlackBody = string.format("%sActor2D/CharacterAvg/%s/%s_%s_001x.png", sRootPath, sAvgCharId, sAvgCharId, sPose)
local spBody = GameResourceLoader.LoadAsset(ResType.Any, sPathBody, typeof(Sprite))
local spFace
if GameResourceLoader.ExistsAsset(sPathFace) == true then
spFace = GameResourceLoader.LoadAsset(ResType.Any, sPathFace, typeof(Sprite))
end
local spBlackBody = spBody
if GameResourceLoader.ExistsAsset(sPathBlackBody) == true then
spBlackBody = GameResourceLoader.LoadAsset(ResType.Any, sPathBlackBody, typeof(Sprite))
end
local sFullPath = string.format("%sActor2D/CharacterAvg/%s/%s.asset", sRootPath, sAvgCharId, sAvgCharId)
local objOffset = GameResourceLoader.LoadAsset(ResType.Any, sFullPath, typeof(CS.Actor2DOffsetData))
local nX, nY = 0, 0
if objOffset == nil then
printError(sFullPath)
return
end
local s, x, y = objOffset:GetOffsetData(PanelId.AvgST, indexOfPose(sPose), true, nX, nY)
local v3OffsetPos = Vector3(x, y, 0)
local v3OffsetScale = Vector3(s, s, 1)
return spBody, spFace, v3OffsetPos, v3OffsetScale, spBlackBody
end
function BaseCtrl:GetAvgPortraitEmojiOffsetData(sAvgCharId, sPose, nEmojiIndex)
local sFullPath = string.format("%sActor2D/CharacterAvg/%s/%s.asset", sRootPath, sAvgCharId, sAvgCharId)
local objOffset = GameResourceLoader.LoadAsset(ResType.Any, sFullPath, typeof(CS.Actor2DOffsetData))
local nX, nY = 0, 0
local s, x, y = objOffset:GetEmojiData(PanelId.AvgST, indexOfPose(sPose), nEmojiIndex, nX, nY)
local v3OffsetPos = Vector3(x, y, 0)
local v3OffsetScale = Vector3(s, math.abs(s), 1)
return v3OffsetPos, v3OffsetScale
end
function BaseCtrl:GetAvgHeadFrameOffsetData(sAvgCharId, sPose, nFrameIndex)
local sFullPath = string.format("%sActor2D/CharacterAvg/%s/%s.asset", sRootPath, sAvgCharId, sAvgCharId)
local objOffset = GameResourceLoader.LoadAsset(ResType.Any, sFullPath, typeof(CS.Actor2DOffsetData))
if nFrameIndex == 2 then
nFrameIndex = 3
end
local nX, nY = 0, 0
local s, x, y = objOffset:Get_AvgCharHeadFrameData(PanelId.AvgST, indexOfPose(sPose), nFrameIndex, nX, nY)
return x, y, s
end
function BaseCtrl:OnEvent_AvgSpeedUp_Timer(nRate)
local n = #self._tbTimer
for i = n, 1, -1 do
local timer = self._tbTimer[i]
if timer ~= nil then
timer:SetSpeed(nRate)
end
end
end
function BaseCtrl:SetAvgCharHeadIconByPrefab(img, sPrefabPath)
local sFullPath = sRootPath .. sPrefabPath
local prefab = GameResourceLoader.LoadAsset(ResType.Any, sFullPath, typeof(GameObject), "UI", self._panel._nPanelId)
NovaAPI.SetImageSpriteWithPrefab(img, prefab)
end
function BaseCtrl:AddTimer(nTargetCount, nInterval, sCallbackName, bAutoRun, bDestroyWhenComplete, nScaleType, tbParam)
local callback
if type(sCallbackName) == "function" then
callback = sCallbackName
else
callback = self[sCallbackName]
end
if type(callback) == "function" then
local timer = TimerManager.Add(nTargetCount, nInterval, self, callback, bAutoRun, bDestroyWhenComplete, nScaleType, tbParam)
if timer ~= nil then
if self:GetPanelId() == PanelId.AvgST and type(self._panel.nSpeedRate) == "number" then
timer:SetSpeed(self._panel.nSpeedRate)
end
table.insert(self._tbTimer, timer)
end
return timer
else
return nil
end
end
function BaseCtrl:_autoRemoveTimer(timer)
local n = #self._tbTimer
for i = n, 1, -1 do
local timer = self._tbTimer[i]
if timer ~= nil and timer:IsUnused() == true then
table.remove(self._tbTimer, i)
end
end
end
function BaseCtrl:CreatePrefabInstance(sPrefabPath, trParent)
local sFullPath = sRootPath .. sPrefabPath
local prefab = GameResourceLoader.LoadAsset(ResType.Any, sFullPath, typeof(Object), "UI", self._panel._nPanelId)
if trParent == nil then
trParent = self.gameObject.transform
end
local goPrefabIns = instantiate(prefab, trParent)
goPrefabIns.name = sPrefabPath
self._mapPrefab[sPrefabPath] = goPrefabIns
return goPrefabIns
end
function BaseCtrl:DestroyPrefabInstance(sPrefabPath)
local goIns = self._mapPrefab[sPrefabPath]
if goIns ~= nil then
destroy(goIns)
self._mapPrefab[sPrefabPath] = nil
end
end
function BaseCtrl:LoadAsset(sPrefabPath, assetType)
local sFullPath = sRootPath .. sPrefabPath
if assetType == nil then
assetType = typeof(Object)
end
local prefab = GameResourceLoader.LoadAsset(ResType.Any, sFullPath, assetType, "UI", self._panel._nPanelId)
if prefab ~= nil then
self._mapLoadAssets[sPrefabPath] = prefab
end
return prefab
end
function BaseCtrl:LoadAssetAsync(sPrefabPath, assetType, callback)
local sFullPath = sRootPath .. sPrefabPath
if assetType == nil then
assetType = typeof(Object)
end
local callBack = function(obj)
if obj ~= nil then
if obj ~= nil then
self._mapLoadAssets[sPrefabPath] = obj
end
if callback ~= nil then
callback(obj)
end
end
end
GameResourceLoader.LoadAssetAsync(ResType.Any, sFullPath, assetType, "UI", self._panel._nPanelId, callBack)
end
function BaseCtrl:UnLoadAsset(sPrefabPath)
local prefab = self._mapLoadAssets[sPrefabPath]
if prefab ~= nil then
prefab = nil
self._mapLoadAssets[sPrefabPath] = nil
end
end
function BaseCtrl:SpawnPrefabInstance(prefab, sLuaClassName, sPoolName, parent)
local goPrefabIns = AdventureModuleHelper.SpawnPrefabInstance(prefab, sPoolName, parent)
local luaClassName = require(sLuaClassName)
local objCtrl = luaClassName.new(goPrefabIns, self._panel)
objCtrl:_Enter()
return objCtrl
end
function BaseCtrl:DespawnPrefabInstance(objCtrl, sPoolName)
if objCtrl ~= nil then
objCtrl:_PreExit()
objCtrl:_Exit()
objCtrl:_Destroy()
AdventureModuleHelper.DespawnPrefabInstance(objCtrl.gameObject, sPoolName)
end
end
function BaseCtrl:BindCtrlByNode(goNode, sCtrlName)
local objCtrl
local luaClass = require(sCtrlName)
if luaClass == nil then
printError("Ctrl Lua not found, path:" .. sCtrlName)
else
objCtrl = luaClass.new(goNode, self._panel)
table.insert(self._panel._tbObjDyncChildCtrl, objCtrl)
objCtrl:_Enter()
end
return objCtrl
end
function BaseCtrl:UnbindCtrlByNode(objCtrl)
objCtrl:_PreExit()
objCtrl:_Exit()
objCtrl:_Destroy()
objCtrl.gameObject = nil
table.remove(self._panel._tbObjDyncChildCtrl, table.indexof(self._panel._tbObjDyncChildCtrl, objCtrl))
end
function BaseCtrl:SetAnimationCallback(animatior, sCallbackName)
local wait = function()
coroutine.yield(CS.UnityEngine.WaitForEndOfFrame())
local time = animatior:GetCurrentAnimatorStateInfo(0).length
self:AddTimer(1, time, sCallbackName, true, true, true)
end
cs_coroutine.start(wait)
end
function BaseCtrl:ParseHitDamageDesc(nHitDamageId, nLevel)
local sDesc = ""
local mapDamage = ConfigTable.GetData_HitDamage(nHitDamageId)
if not mapDamage then
printError("该 hit damage id 找不到数据:" .. nHitDamageId)
sDesc = string.format("<color=#FF0000>%d</color>", nHitDamageId)
return sDesc
end
local nPercent = mapDamage.SkillPercentAmend[nLevel]
local nAbs = mapDamage.SkillAbsAmend[nLevel]
if not nPercent or not nAbs then
printError(string.format("该技能等级在 HitDamage 表中找不到数据, hit damage id:%d, level:%d", nHitDamageId, nLevel))
sDesc = string.format("<color=#FF0000>%d</color>", nHitDamageId)
return sDesc
end
nPercent = nPercent * ConfigData.IntFloatPrecision
nPercent = FormatNum(nPercent)
nAbs = FormatNum(nAbs)
local sPercent = nPercent == 0 and "" or tostring(nPercent) .. "%%"
local sAbs = nAbs == 0 and "" or tostring(nAbs)
if nPercent ~= 0 and nAbs ~= 0 then
sDesc = sPercent .. "+" .. sAbs
else
sDesc = sPercent .. sAbs
end
return sDesc
end
function BaseCtrl:ThousandsNumber(number)
local formatted = tostring(number)
local k
while true do
formatted, k = string.gsub(formatted, "^(.*-?%d+)(%d%d%d)", "%1,%2")
if k == 0 then
break
end
end
return formatted
end
function BaseCtrl:GetGamepadUINode()
local tbNode = {}
if self.gameObject == nil or type(self._mapNodeConfig) ~= "table" then
return tbNode
end
local add = function(sKey, mapConfig, sComponentName)
if mapConfig.sComponentName == sComponentName then
local nCount = mapConfig.nCount
if type(nCount) == "number" then
for i = 1, nCount do
local mapNode = self._mapNode[sKey][i]
if mapNode then
table.insert(tbNode, {
mapNode = mapNode,
sComponentName = sComponentName,
sAction = mapConfig.sAction
})
end
end
else
local mapNode = self._mapNode[sKey]
if mapNode then
table.insert(tbNode, {
mapNode = mapNode,
sComponentName = sComponentName,
sAction = mapConfig.sAction
})
end
end
end
end
for sKey, mapConfig in pairs(self._mapNodeConfig) do
add(sKey, mapConfig, "NaviButton")
add(sKey, mapConfig, "GamepadScroll")
end
return tbNode
end
return BaseCtrl