local Avg_4_TalkCtrl = class("Avg_4_TalkCtrl", BaseCtrl) local GameResourceLoader = require("Game.Common.Resource.GameResourceLoader") local GamepadUIManager = require("GameCore.Module.GamepadUIManager") local ResType = GameResourceLoader.ResType local WwiseAudioMgr = CS.WwiseAudioManager.Instance local LayoutRebuilder = CS.UnityEngine.UI.LayoutRebuilder local AUTO_PLAY_WAITING_DEFAULT = 3 local AUTO_PLAY_WAITING_VOICE = 0.1 Avg_4_TalkCtrl._mapNodeConfig = { trCameraAperture = { sNodeName = "CameraAperture", sComponentName = "Transform" }, cg_CameraAperture = { sNodeName = "====CameraAperture====", sComponentName = "CanvasGroup" }, btnClickToGoOn = { sComponentName = "Button", callback = "OnBtnClick_GoOn" }, btnShortcutClickToGoOn = { sComponentName = "NaviButton", callback = "OnBtnClick_GoOn" }, rubyTMP_ContentElement = { sComponentName = "RubyTextMeshProUGUI" }, rtRubyTMP = { sNodeName = "rubyTMP_ContentElement", sComponentName = "RectTransform" }, canvasGroup_Talk = { sNodeName = "----Talk----", sComponentName = "CanvasGroup" }, shake_Talk = { sNodeName = "----Talk----", sComponentName = "GameObject" }, imgTalkNameBg = {sComponentName = "Image"}, trWaiting_Talk = { sNodeName = "--Waiting_Talk--", sComponentName = "Transform" }, rubyTmp_Talk = { sComponentName = "RubyTextMeshProUGUI" }, txtName_Talk = {sComponentName = "TMP_Text"}, btnSvTalk = { sNodeName = "sv_Talk", sComponentName = "UIButton", callback = "OnBtnClick_GoOn" }, sv_Talk = { sComponentName = "GamepadScroll" }, imgThinkMask = {sComponentName = "Image"}, canvasGroup_SayThink = { sNodeName = "----SayThink----", sComponentName = "CanvasGroup" }, shake_SayThink = { sNodeName = "----SayThink----", sComponentName = "GameObject" }, animSwitchSayThinkBg = { sNodeName = "----SayThink----", sComponentName = "Animator" }, trWaiting_SayThink = { sNodeName = "--Waiting_SayThink--", sComponentName = "Transform" }, rubyTmp_SayThink = { sComponentName = "RubyTextMeshProUGUI" }, btnSvSayThink = { sNodeName = "sv_SayThink", sComponentName = "UIButton", callback = "OnBtnClick_GoOn" }, sv_SayThink = { sComponentName = "GamepadScroll" }, rtHeadPos = { sComponentName = "RectTransform" }, canvasGroup_Head = { sNodeName = "rtHeadPos", sComponentName = "CanvasGroup" }, canvasGroup_Film = { sNodeName = "----Film----", sComponentName = "CanvasGroup" }, rubyTmp_Film = { sComponentName = "RubyTextMeshProUGUI" }, canvasGroup_Dialog_1L = { sNodeName = "----Dialog_1L----", sComponentName = "CanvasGroup" }, shake_Dialog_1L = { sNodeName = "----Dialog_1L----", sComponentName = "GameObject" }, imgTalkNameBg_1L = {sComponentName = "Image"}, trWaiting_Dialog_1L = { sNodeName = "--Waiting_Dialog_1L--", sComponentName = "Transform" }, rubyTmp_1L = { sComponentName = "RubyTextMeshProUGUI" }, txtName_Dialog_1L = {sComponentName = "TMP_Text"}, btnSvD1L = { sNodeName = "sv_Dialog_1L", sComponentName = "UIButton", callback = "OnBtnClick_GoOn" }, sv_Dialog_1L = { sComponentName = "GamepadScroll" }, canvasGroup_Dialog_1R = { sNodeName = "----Dialog_1R----", sComponentName = "CanvasGroup" }, shake_Dialog_1R = { sNodeName = "----Dialog_1R----", sComponentName = "GameObject" }, imgTalkNameBg_1R = {sComponentName = "Image"}, trWaiting_Dialog_1R = { sNodeName = "--Waiting_Dialog_1R--", sComponentName = "Transform" }, rubyTmp_1R = { sComponentName = "RubyTextMeshProUGUI" }, txtName_Dialog_1R = {sComponentName = "TMP_Text"}, btnSvD1R = { sNodeName = "sv_Dialog_1R", sComponentName = "UIButton", callback = "OnBtnClick_GoOn" }, sv_Dialog_1R = { sComponentName = "GamepadScroll" }, canvasGroup_Dialog_2L = { sNodeName = "----Dialog_2L----", sComponentName = "CanvasGroup" }, shake_Dialog_2L = { sNodeName = "----Dialog_2L----", sComponentName = "GameObject" }, imgTalkNameBg_2L = {sComponentName = "Image"}, trWaiting_Dialog_2L = { sNodeName = "--Waiting_Dialog_2L--", sComponentName = "Transform" }, rubyTmp_2L = { sComponentName = "RubyTextMeshProUGUI" }, txtName_Dialog_2L = {sComponentName = "TMP_Text"}, btnSvD2L = { sNodeName = "sv_Dialog_2L", sComponentName = "UIButton", callback = "OnBtnClick_GoOn" }, sv_Dialog_2L = { sComponentName = "GamepadScroll" }, canvasGroup_Dialog_2R = { sNodeName = "----Dialog_2R----", sComponentName = "CanvasGroup" }, shake_Dialog_2R = { sNodeName = "----Dialog_2R----", sComponentName = "GameObject" }, imgTalkNameBg_2R = {sComponentName = "Image"}, trWaiting_Dialog_2R = { sNodeName = "--Waiting_Dialog_2R--", sComponentName = "Transform" }, rubyTmp_2R = { sComponentName = "RubyTextMeshProUGUI" }, txtName_Dialog_2R = {sComponentName = "TMP_Text"}, btnSvD2R = { sNodeName = "sv_Dialog_2R", sComponentName = "UIButton", callback = "OnBtnClick_GoOn" }, sv_Dialog_2R = { sComponentName = "GamepadScroll" }, canvasGroup_Center = { sNodeName = "----Center----", sComponentName = "CanvasGroup" }, rubyTmp_Center = { sComponentName = "RubyTextMeshProUGUI" }, imgContentBg_Center = {}, canvasGroup_CGTalk = { sNodeName = "----CGTalk----", sComponentName = "CanvasGroup" }, imgContentLine = {}, trWaiting_CGTalk = { sNodeName = "--Waiting_CGTalk--", sComponentName = "Transform" }, rubyTmp_CGTalk = { sComponentName = "RubyTextMeshProUGUI" }, txtName_CGTalk = {sComponentName = "TMP_Text"}, canvasGroup_FS = { sNodeName = "----FullScreen----", sComponentName = "CanvasGroup" }, btnSvFS = { sNodeName = "svFS", sComponentName = "UIButton", callback = "OnBtnClick_GoOn" }, svFS = { sComponentName = "GamepadScroll" }, rtWaiting_FS = { sNodeName = "--Waiting_FS--", sComponentName = "RectTransform" }, rubyTmp_FS = { sComponentName = "RubyTextMeshProUGUI" }, rubyTmp_FS_EndLine = { sComponentName = "RubyTextMeshProUGUI" }, rtEndLine = { sNodeName = "rubyTmp_FS_EndLine", sComponentName = "RectTransform" }, rubyTmp_FS_Total = { sComponentName = "RubyTextMeshProUGUI" }, rtTotal = { sNodeName = "rubyTmp_FS_Total", sComponentName = "RectTransform" }, rtWaiting = { sComponentName = "RectTransform" }, rtWaiting_White = { sComponentName = "RectTransform" }, animWaiting = { sNodeName = "goWaitingAnim", sComponentName = "Animator" }, animWaiting_White = { sNodeName = "goWaitingAnim_White", sComponentName = "Animator" }, goEmptyBottom = {}, imgFullScreenBlockInput = { sNodeName = "full_screen_image_temp_block_btn", sComponentName = "Image" } } Avg_4_TalkCtrl._mapEventConfig = { [EventId.AvgSetAutoPlay] = "OnEvent_AvgSetAutoPlay", [EventId.AvgShowHideTalkUI] = "OnEvent_AvgShowHideTalkUI", [EventId.AvgClearTalk] = "OnEvent_ClearTalk", [EventId.AvgL2DAnimEvent_Start] = "OnL2DAnimEvent_RunNextCmd", [EventId.AvgL2DAnimEvent_Next] = "OnL2DAnimEvent_GoOn", [EventId.AvgL2DAnimEvent_End] = "OnL2DAnimEvent_BtnClick", [EventId.AvgL2DAnimEvent_Done] = "OnL2DAnimEvent_Done", [EventId.AvgVoiceDuration] = "OnEvent_AvgVoiceDuration", [EventId.AvgSpeedUp] = "OnEvent_AvgSpeedUp", GamepadUIChange = "OnEvent_GamepadUIChange", GamepadUIReopen = "OnEvent_Reopen", AVG_SetCameraAperture = "OnEvent_AVG_SetCameraAperture" } function Avg_4_TalkCtrl:Awake() self.rootCanvasGroup = self.gameObject:GetComponent("CanvasGroup") self.sNone = "" self.sParagraphSignal = "==P==" self.sBreakSignal = "==B==" self.sWaitSignal = "==W==" self.sAutoParagraphSignal = "==A(.+)==" self.sCenterBgOff = "==Off==" self.nContentBgFadeDuration = 0.35 self.nHeadInOutAnimDuration = 0.5 self.nContentTextDelay_1 = 0.2 self.nContentTextDelay_2 = 0.3 self.bIsAutoPlaying = false self.twDOText = nil self.tbPage = nil self.nPageIndex = nil self.curCanvasGroup = nil self.curTMP = nil self.sPartialContent = self.sNone self.nClearType = 0 self.timerAutoPlayWaiting = nil self.mapPresetShakeChar = nil self.mapPresetShakeTalk = nil self.bNeedWaitVoiceFinish = false self.bNeedPlayPageSound = false self.bForceDisableBtn_LogHide = false self.tbLogData = {} self:_SetAutoLineWrap(true) end function Avg_4_TalkCtrl:OnEnable() self:AddGamepadUINode() end function Avg_4_TalkCtrl:OnDisable() self.mapPresetShakeChar = nil self.mapPresetShakeTalk = nil if self.twDOText ~= nil then self.twDOText:Kill() self.twDOText = nil end if self.timerVoicePlayWaiting ~= nil then self.timerVoicePlayWaiting:Cancel() self.timerVoicePlayWaiting = nil WwiseAudioMgr:WwiseVoice_StopInAVG() end self.bNeedWaitVoiceFinish = false end function Avg_4_TalkCtrl:_LoadPresetShake() if self.mapPresetShakeChar == nil then self.mapPresetShakeChar = {} for _, data in ipairs(self._panel.tbAvgPreset.CharShakeType) do local sKey = data[1] self.mapPresetShakeChar[sKey] = data[2] end end if self.mapPresetShakeTalk == nil then self.mapPresetShakeTalk = {} for _, data in ipairs(self._panel.tbAvgPreset.BgShakeType) do local sKey = data[1] self.mapPresetShakeTalk[sKey] = data[2] end end end function Avg_4_TalkCtrl:_SetAutoLineWrap(bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_Talk, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_SayThink, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_1L, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_1R, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_2L, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_2R, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_Center, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_CGTalk, bEnable) NovaAPI.SetTMP_AutoLineWrap(self._mapNode.rubyTmp_FS, bEnable) end function Avg_4_TalkCtrl:_CheckLogBtnForceDisable(sContent) if string.find(sContent, self.sBreakSignal) ~= nil then self.bForceDisableBtn_LogHide = true elseif string.find(sContent, self.sWaitSignal) ~= nil then self.bForceDisableBtn_LogHide = true elseif string.find(sContent, self.sAutoParagraphSignal) ~= nil then self.bForceDisableBtn_LogHide = true else self.bForceDisableBtn_LogHide = false end end function Avg_4_TalkCtrl:_StartTimerAutoPlayWaiting(nWaitTime) if self:GetPanelId() ~= PanelId.AvgST then return end if nWaitTime == nil then nWaitTime = AUTO_PLAY_WAITING_DEFAULT end if self.timerAutoPlayWaiting == nil then self.timerAutoPlayWaiting = self:AddTimer(1, nWaitTime, "_AutoPlayTimerCallback", true, false, true) else self.timerAutoPlayWaiting:Reset(nil, nWaitTime) end end function Avg_4_TalkCtrl:_PauseTimerAutoPlayWaiting() if self.timerAutoPlayWaiting ~= nil then self.timerAutoPlayWaiting:Pause() end end function Avg_4_TalkCtrl:_AutoPlayTimerCallback(_timer) self:OnBtnClick_GoOn(self._mapNode.btnClickToGoOn, true) end function Avg_4_TalkCtrl:_TempBlockInput() NovaAPI.SetImageRaycastTarget(self._mapNode.imgFullScreenBlockInput, true) local func = function() NovaAPI.SetImageRaycastTarget(self._mapNode.imgFullScreenBlockInput, false) end self:AddTimer(1, 0.15, func, true, true, true) end function Avg_4_TalkCtrl:_SetBtnEnable(bEnable) if self.bInL2DTalk == true then bEnable = false end if bEnable == true then self:_TempBlockInput() end NovaAPI.SetButtonInteractable(self._mapNode.btnClickToGoOn, bEnable == true) NovaAPI.SetButtonInteractable(self._mapNode.btnShortcutClickToGoOn, bEnable == true) self._mapNode.btnClickToGoOn.gameObject:SetActive(bEnable) self._mapNode.btnShortcutClickToGoOn.gameObject:SetActive(bEnable) NovaAPI.SetCanvasGroupInteractable(self.rootCanvasGroup, bEnable == true) NovaAPI.SetCanvasGroupBlocksRaycasts(self.rootCanvasGroup, bEnable == true) if bEnable and self._panel.sCurGamepadUI == "Talk" then GamepadUIManager.ClearSelectedUI() GamepadUIManager.SetSelectedUI(self._mapNode.btnShortcutClickToGoOn.gameObject) end end function Avg_4_TalkCtrl:OnBtnClick_GoOn(btn, bOnTimer) if self:GetPanelId() ~= PanelId.AvgST then return end if self.bInL2DTalk ~= true and self.bNeedWaitVoiceFinish ~= true and self.timerVoicePlayWaiting ~= nil then self.timerVoicePlayWaiting:Cancel() self.timerVoicePlayWaiting = nil end if self.twDOText ~= nil then self.twDOText:Kill(true) self.twDOText = nil return end if self.bIsAutoPlaying == true and bOnTimer ~= true then self:_PauseTimerAutoPlayWaiting() end if self.tbPage == nil then return end local sType = self.tbPage[self.nPageIndex][2] if sType == "Subtitle" then self:_SetBtnEnable(false) if self.nClearType == 0 then self:_ClearTalk() end self:_PlayPageSound(self.bIsAutoPlaying == true and bOnTimer == true) self.tbPage = nil self.nPageIndex = nil WwiseAudioMgr:WwiseVoice_StopInAVG() self:_RunNextCmd() elseif sType == "Break" or sType == "Paragraph" then self:_ProcAlphaCombine(sType == "Paragraph") self:_SetWaitingVisible(false) if self.nPageIndex == #self.tbPage then self:_SetBtnEnable(false) self:_SetScrollable(false) if self.nClearType == 0 then self:_ClearTalk() end self:_PlayPageSound(self.bIsAutoPlaying == true and bOnTimer == true) self.tbPage = nil self.nPageIndex = nil self.sPartialContent = self.sNone NovaAPI.SetText_RubyTMP(self._mapNode.rubyTMP_ContentElement, self.sNone) self:_RunNextCmd() else self.nPageIndex = self.nPageIndex + 1 self:_ProcParagraph() end end end function Avg_4_TalkCtrl:_PlayPageSound(bAuto) if self.bNeedPlayPageSound ~= true then return end if bAuto == true then WwiseAudioMgr:PlaySound("ui_dialog_auto") else WwiseAudioMgr:PlaySound("ui_dialog_click") end end function Avg_4_TalkCtrl:OnEvent_AvgSetAutoPlay(bAuto, bByInit) self.bIsAutoPlaying = bAuto local sTrigger = "tManual" if self.bIsAutoPlaying == true then sTrigger = "tAuto" end self._mapNode.animWaiting:SetTrigger(sTrigger) self._mapNode.animWaiting_White:SetTrigger(sTrigger) if bByInit == true then return end if self.bNeedWaitVoiceFinish == true then if self:_CheckTalkContentTextIsDone() ~= true then return end if self.timerVoicePlayWaiting == nil then if self.bIsAutoPlaying == true then self:_StartTimerAutoPlayWaiting() else self:_PauseTimerAutoPlayWaiting() end end elseif self.twDOText == nil and self.tbPage ~= nil then local sType = self.tbPage[self.nPageIndex][2] if sType == "Break" or sType == "Paragraph" or sType == "Subtitle" then if self.bIsAutoPlaying == true then if self.timerVoicePlayWaiting == nil then self:_StartTimerAutoPlayWaiting() end else self:_PauseTimerAutoPlayWaiting() end end end end function Avg_4_TalkCtrl:OnEvent_AvgShowHideTalkUI(bVisible) NovaAPI.SetCanvasGroupAlpha(self.rootCanvasGroup, bVisible == true and 1 or 1.0E-4) NovaAPI.SetCanvasGroupInteractable(self.rootCanvasGroup, bVisible == true) NovaAPI.SetCanvasGroupBlocksRaycasts(self.rootCanvasGroup, bVisible == true) NovaAPI.SetButtonInteractable(self._mapNode.btnClickToGoOn, bVisible == true) NovaAPI.SetButtonInteractable(self._mapNode.btnShortcutClickToGoOn, bVisible == true) if bVisible and self._panel.sCurGamepadUI == "Talk" then GamepadUIManager.ClearSelectedUI() GamepadUIManager.SetSelectedUI(self._mapNode.btnShortcutClickToGoOn.gameObject) end end function Avg_4_TalkCtrl:OnEvent_ClearTalk() self:_ClearTalk() self:_SetBtnEnable(false) end function Avg_4_TalkCtrl:_ClearTalk() if self.twDOText ~= nil then self.twDOText:Kill() self.twDOText = nil end if self.curCanvasGroup == nil then return end local nDelayTime if self.curCanvasGroup == self._mapNode.canvasGroup_SayThink and NovaAPI.GetCanvasGroupAlpha(self._mapNode.canvasGroup_Head) > 0 then nDelayTime = self.nHeadInOutAnimDuration - self.nContentBgFadeDuration end NovaAPI.SetCanvasGroupInteractable(self.curCanvasGroup, false) NovaAPI.SetCanvasGroupBlocksRaycasts(self.curCanvasGroup, false) local tw = self.curCanvasGroup:DOFade(0, self.nContentBgFadeDuration):SetUpdate(true):SetEase(Ease.InSine) if nDelayTime ~= nil then tw:SetDelay(nDelayTime) end self.curTMP = nil self.curCanvasGroup = nil NovaAPI.ImageDoFade(self._mapNode.imgThinkMask, 0, 0.1, true) NovaAPI.StopShakeEffect(self._mapNode.shake_Talk) NovaAPI.StopShakeEffect(self._mapNode.shake_SayThink) NovaAPI.StopShakeEffect(self._mapNode.shake_Dialog_1L) NovaAPI.StopShakeEffect(self._mapNode.shake_Dialog_1R) NovaAPI.StopShakeEffect(self._mapNode.shake_Dialog_2L) NovaAPI.StopShakeEffect(self._mapNode.shake_Dialog_2R) self:_SetWaitingVisible(false) end function Avg_4_TalkCtrl:OnL2DAnimEvent_RunNextCmd() self:_RunNextCmd(true) end function Avg_4_TalkCtrl:OnL2DAnimEvent_GoOn() if self.twDOText ~= nil then self.twDOText:Kill(true) self.twDOText = nil end self:SetGoOn() end function Avg_4_TalkCtrl:OnL2DAnimEvent_BtnClick() if self.twDOText ~= nil then self.twDOText:Kill(true) self.twDOText = nil end if type(self.tbPage) == "table" and self.nPageIndex == #self.tbPage and type(self.tbLogData) == "table" then EventManager.Hit(EventId.AvgMarkLog, self.tbLogData) self.tbLogData = nil end self:OnBtnClick_GoOn() end function Avg_4_TalkCtrl:OnL2DAnimEvent_Done() self.bInL2DTalk = false if self.twDOText ~= nil then self.twDOText:Kill(true) self.twDOText = nil end self:_SetBtnEnable(true) self:_SetWaitingVisible(true) if self.bIsAutoPlaying == true then self:_StartTimerAutoPlayWaiting() end end function Avg_4_TalkCtrl:OnEvent_AvgVoiceDuration(nDuration) if self:GetPanelId() == PanelId.AvgEditor then return end if self.bProcVoiceCallbackEvent ~= true then return end self.bProcVoiceCallbackEvent = false if self.bInL2DTalk == true then return end if self.timerVoicePlayWaiting ~= nil then self.timerVoicePlayWaiting:Cancel() self.timerVoicePlayWaiting = nil WwiseAudioMgr:WwiseVoice_StopInAVG() end self.timerVoicePlayWaiting = self:AddTimer(1, nDuration, "_EndPlayTalkVoice", true, true, true) end function Avg_4_TalkCtrl:_EndPlayTalkVoice(_timer) self.timerVoicePlayWaiting = nil if self:_CheckTalkContentTextIsDone() ~= true then return elseif self.bNeedWaitVoiceFinish == true then if self.bSubtitle == true then self:_SubtitleDone(nil, AUTO_PLAY_WAITING_VOICE) elseif self.bExParagraph == true then self:_ParagraphDoneEx() else self:_ParagraphDone(AUTO_PLAY_WAITING_VOICE) end elseif self.bIsAutoPlaying == true then self:_StartTimerAutoPlayWaiting(AUTO_PLAY_WAITING_VOICE) end end function Avg_4_TalkCtrl:OnEvent_AvgSpeedUp(nRate) if self:GetPanelId() ~= PanelId.AvgST then return end self:OnEvent_AvgSpeedUp_Timer(nRate) NovaAPI.SetAnimatorSpeed(self._mapNode.animSwitchSayThinkBg, nRate) NovaAPI.SetAnimatorSpeed(self._mapNode.animWaiting, nRate) NovaAPI.SetAnimatorSpeed(self._mapNode.animWaiting_White, nRate) end function Avg_4_TalkCtrl:_SwitchSayThink(nType, bReset) if nType == 1 or nType == 2 then if self.nCurSayThink == nType then return end local sColor = nType == 1 and "#132C47" or "#F1F4F6" NovaAPI.SetTextColor_RubyTMP(self._mapNode.rubyTmp_SayThink, sColor) local sTriggerName if nType == 1 then sTriggerName = "tPlayToSay" if bReset == true then sTriggerName = "tSetToSay" end elseif nType == 2 then sTriggerName = "tPlayToThink" if bReset == true then sTriggerName = "tSetToThink" end end self._mapNode.animSwitchSayThinkBg:SetTrigger(sTriggerName) self.nCurSayThink = nType end end function Avg_4_TalkCtrl:_PlayHeadInOutAnim(nType) if nType == 0 then return end local tbHeadAnimData = { { 0, 1, -78, -78, "OutSine" }, { 1, 1, -178, -78, "OutBack" }, { 1, 0, -78, -78, "InSine" }, { 1, 1, -78, -178, "InBack" } } local data = tbHeadAnimData[nType] local nAlpha_From = data[1] local nAlpha_To = data[2] local nPosY_From = data[3] local nPosY_To = data[4] local sEaseType = data[5] self._mapNode.canvasGroup_Head:DOKill() self._mapNode.rtHeadPos:DOKill() NovaAPI.SetCanvasGroupAlpha(self._mapNode.canvasGroup_Head, nAlpha_From) self._mapNode.rtHeadPos.anchoredPosition = Vector2(-9, nPosY_From) if nAlpha_From ~= nAlpha_To then self._mapNode.canvasGroup_Head:DOFade(nAlpha_To, self.nHeadInOutAnimDuration):SetUpdate(true):SetEase(Ease[sEaseType]) end if nPosY_From ~= nPosY_To then self._mapNode.rtHeadPos:DOAnchorPosY(nPosY_To, self.nHeadInOutAnimDuration):SetUpdate(true):SetEase(Ease[sEaseType]) end end function Avg_4_TalkCtrl:_SwitchWaitingRoot(trParent) local rt = self._mapNode.rtWaiting if self.bWhite ~= nil then rt = self._mapNode.rtWaiting_White end rt:SetParent(trParent) rt.anchoredPosition = Vector2.zero end function Avg_4_TalkCtrl:_SetWaitingVisible(bVisible) if self.bInL2DTalk == true then bVisible = false end local rt = self._mapNode.rtWaiting if self.bWhite ~= nil then rt = self._mapNode.rtWaiting_White end rt.localScale = bVisible == true and Vector3.one or Vector3.zero EventManager.Hit(EventId.AvgLogBtnEnable, bVisible == true) if bVisible == true and type(self.tbPage) == "table" and self.nPageIndex == #self.tbPage and type(self.tbLogData) == "table" then EventManager.Hit(EventId.AvgMarkLog, self.tbLogData) self.tbLogData = nil end end function Avg_4_TalkCtrl:_ResetWaitingPos() local nX, nY, bCanScroll = 0, 0, false if type(self.tbPage) == "table" and type(self.nPageIndex) == "number" then local tbPageData = self.tbPage[self.nPageIndex] if type(tbPageData) == "table" then local sContent = tbPageData[1] local sType = tbPageData[2] if type(sContent) == "string" and sContent ~= "" and sType == "Paragraph" then local nSVFS_Width, nSVGS_Height = 1570, 519 local tbSplit = string.split(sContent, "\n") local nLen = #tbSplit local sEndLineContent = tbSplit[nLen] NovaAPI.SetText_RubyTMP(self._mapNode.rubyTmp_FS_EndLine, sEndLineContent) LayoutRebuilder.ForceRebuildLayoutImmediate(self._mapNode.rtEndLine) nX = self._mapNode.rtEndLine.rect.width if nSVFS_Width < nX then nX = nX % nSVFS_Width end if string.find(sEndLineContent, "") ~= nil then nX = nSVFS_Width elseif string.find(sEndLineContent, "") ~= nil then nX = (nSVFS_Width + nX) / 2 end local sTotalContent = NovaAPI.GetText_RubyTMP(self._mapNode.rubyTmp_FS) NovaAPI.SetText_RubyTMP(self._mapNode.rubyTmp_FS_Total, sTotalContent) LayoutRebuilder.ForceRebuildLayoutImmediate(self._mapNode.rtTotal) nY = self._mapNode.rtTotal.rect.height bCanScroll = nSVGS_Height < nY if nSVGS_Height >= nY then nY = nSVGS_Height - nY else nY = 0 end end end end self:_SetScrollable(bCanScroll) self._mapNode.rtWaiting_FS.anchoredPosition = Vector2(nX, nY) end function Avg_4_TalkCtrl:_SetScrollable(bEnable) NovaAPI.SetCanvasGroupInteractable(self._mapNode.canvasGroup_FS, bEnable == true) NovaAPI.SetCanvasGroupBlocksRaycasts(self._mapNode.canvasGroup_FS, bEnable == true) end function Avg_4_TalkCtrl:_ProcParagraph(nDelayTime) if self.twDOText ~= nil then self.twDOText:Kill(false) self.twDOText = nil end local tbPageData = self.tbPage[self.nPageIndex] local sContent = tbPageData[1] local sType = tbPageData[2] self:_SetScrollable(false) NovaAPI.SetText_RubyTMP(self._mapNode.rubyTMP_ContentElement, self.sNone) if string.find(sContent, self.sAutoParagraphSignal) ~= nil then sContent = string.gsub(sContent, "", self.sNone) local nDuration = tonumber(string.match(sContent, self.sAutoParagraphSignal)) sContent = string.gsub(sContent, self.sAutoParagraphSignal, self.sNone) self.tbPage[self.nPageIndex][1] = sContent self.sContent = sContent self._mapNode.rtRubyTMP.anchoredPosition = Vector2(0, 2000) self.twDOText = DOTween.Sequence() local tw = self._mapNode.rtRubyTMP:DOAnchorPosX(255, 0.5):SetUpdate(true) tw.onUpdate = dotween_callback_handler(self, self._JointContentEx) self.twDOText:Append(tw) if 0 < nDuration then self.bExParagraph = true self.twDOText:AppendInterval(nDuration) self.twDOText:AppendCallback(dotween_callback_handler(self, self._ParagraphDoneEx)) else self.twDOText:AppendInterval(nDuration * -1) self.twDOText:AppendCallback(dotween_callback_handler(self, self._ParagraphDone)) end self.twDOText:SetUpdate(true) else self:_SetBtnEnable(true) self.twDOText = NovaAPI.DOText_RubyTMP(self._mapNode.rubyTMP_ContentElement, sContent, CalcTextAnimDuration(sContent, self._panel.nCurLanguageIdx)) if self.twDOText ~= nil then self.twDOText:SetUpdate(true) self.twDOText.onUpdate = dotween_callback_handler(self, self._JointContent) self.twDOText.onComplete = dotween_callback_handler(self, self._ParagraphDone) if type(nDelayTime) == "number" then self.twDOText:SetDelay(nDelayTime) end elseif type(nDelayTime) == "number" then self.twDOText = TweenExtensions.DOWait(nDelayTime):SetUpdate(true) self.twDOText.onComplete = dotween_callback_handler(self, self._ParagraphDone) else self:_ParagraphDone() end end end function Avg_4_TalkCtrl:_JointContent() if self.curTMP ~= nil then NovaAPI.SetText_RubyTMP(self.curTMP, self.sPartialContent, self._mapNode.rubyTMP_ContentElement) end end function Avg_4_TalkCtrl:_ParagraphDone(n) self.twDOText = nil if self.bNeedWaitVoiceFinish == true and self.timerVoicePlayWaiting ~= nil then self:_SetBtnEnable(false) self:_SetScrollable(false) return end if self.tbPage == nil then return end local sType = self.tbPage[self.nPageIndex][2] self:_SetWaitingVisible(self.nPageIndex == #self.tbPage or sType == "Paragraph") self:_SetBtnEnable(sType == "Break" or sType == "Paragraph") if sType == "Wait" then self:_ProcAlphaCombine(false) self:_RunNextCmd() else if self.nCurTalkType == 10 and sType == "Paragraph" then self:_ResetWaitingPos() end if self.bIsAutoPlaying == true and self.bInL2DTalk ~= true and self.timerVoicePlayWaiting == nil then if n == nil then n = AUTO_PLAY_WAITING_DEFAULT end self:_StartTimerAutoPlayWaiting(n) end end end function Avg_4_TalkCtrl:_JointContentEx() if self.curTMP == nil then return end local sContent = self.sContent local sAlpha = string.format("", math.floor(self._mapNode.rtRubyTMP.anchoredPosition.x)) local mapReplacePair = {} for src in string.gmatch(sContent, "") do mapReplacePair[src] = src .. sAlpha end for k, v in pairs(mapReplacePair) do sContent = string.gsub(sContent, k, v) end sContent = string.gsub(sContent, "", "" .. sAlpha) sContent = string.gsub(sContent, "", "" .. sAlpha) sContent = sAlpha .. sContent NovaAPI.SetText_RubyTMP(self._mapNode.rubyTMP_ContentElement, sContent) NovaAPI.SetText_RubyTMP(self.curTMP, self.sPartialContent, self._mapNode.rubyTMP_ContentElement) end function Avg_4_TalkCtrl:_ParagraphDoneEx() self.twDOText = nil if self.bNeedWaitVoiceFinish == true and self.timerVoicePlayWaiting ~= nil then return end self.bExParagraph = nil self:OnBtnClick_GoOn() end function Avg_4_TalkCtrl:_RunNextCmd(bForceByL2DAnimEvent) if self.bInL2DTalk == true and bForceByL2DAnimEvent ~= true then return end if self:GetPanelId() == PanelId.AvgST then self._panel:RUN() end end function Avg_4_TalkCtrl:_SubtitleDone(_timer, n) self.timerSubtitle = nil if self.bExParagraph == true then self.bExParagraph = nil self:OnBtnClick_GoOn() return end if self.bNeedWaitVoiceFinish == true and self.timerVoicePlayWaiting ~= nil then self:_SetBtnEnable(false) return end self:_SetBtnEnable(true) if self.bIsAutoPlaying == true and self.timerVoicePlayWaiting == nil then if n == nil then n = AUTO_PLAY_WAITING_DEFAULT end self:_StartTimerAutoPlayWaiting(n) end end function Avg_4_TalkCtrl:_ProcAlphaCombine(bAlpha) local sCurPageContent = self.tbPage[self.nPageIndex][1] if bAlpha == true then sCurPageContent = string.gsub(sCurPageContent, "", self.sNone) local sAlpha = "" local mapReplacePair = {} for src in string.gmatch(sCurPageContent, "") do mapReplacePair[src] = src .. sAlpha end for k, v in pairs(mapReplacePair) do sCurPageContent = string.gsub(sCurPageContent, k, v) end sCurPageContent = string.gsub(sCurPageContent, "", "" .. sAlpha) sCurPageContent = string.gsub(sCurPageContent, "", "" .. sAlpha) sCurPageContent = sAlpha .. sCurPageContent end self.sPartialContent = self.sPartialContent .. sCurPageContent end function Avg_4_TalkCtrl:_ProcRubyPos(sContent) local mapRubyPos = {} for sFullRubyText in string.gmatch(sContent, ".-") do local sBaseText = string.gsub(sFullRubyText, "", self.sNone) sBaseText = string.gsub(sBaseText, "", self.sNone) local sRubyText = string.gsub(sFullRubyText, sBaseText, self.sNone) sRubyText = string.gsub(sRubyText, "", self.sNone) sRubyText = string.gsub(sRubyText, "", self.sNone) local a, b = 0, 0 local bSucc, nRPos1, nRPos2 = NovaAPI.GetRubyPos(self.curTMP, sBaseText, sRubyText, a, b) local sRpos = string.format("", nRPos1, nRPos2) local sReplace = string.format("%s%s", sRubyText, sRpos, sBaseText) mapRubyPos[sFullRubyText] = sReplace printLog(string.format("base:%s,ruby:%s,replace:%s", sBaseText, sRubyText, sReplace)) end for k, v in pairs(mapRubyPos) do sContent = string.gsub(sContent, k, v) end return sContent end function Avg_4_TalkCtrl:_Ignore_PBW(sContent) sContent = string.gsub(sContent, self.sParagraphSignal, self.sNone) sContent = string.gsub(sContent, self.sBreakSignal, self.sNone) sContent = string.gsub(sContent, self.sWaitSignal, self.sNone) sContent = string.gsub(sContent, self.sAutoParagraphSignal, self.sNone) return sContent end function Avg_4_TalkCtrl:_ProcTmpPosY(sContent, bIsAsideTalk) if self.curTMP == nil or sContent == nil then return end local rtTmp = self.curTMP.gameObject:GetComponent("RectTransform") local nPosY = 90 if bIsAsideTalk ~= true then local tb = string.split(sContent, "\n") if tb ~= nil and string.find(tb[1], "