local UIPlotReview = UIViewClass() local LineAndPointType = { ShortOneLine = 1, LongOneLine = 2, ShortOneToUpLine = 3, LongOneToUpLine = 4, ShortOneToDownLine = 5, LongOneToDownLine = 6, LowPointRoot = 7, HighPointRoot = 8, } -------------------- function UIPlotReview:OnOpened(context) self:RegistSystemEvent(EventID.PlotReview_RefreshMap, self.RefreshPlotReviewMap) self:RegistSystemEvent(EventID.PlotReview_EndCG, self.EndCG) self:RegistSystemEvent(EventID.PlotReview_CancelChapterRp, self.RefreshAllRp) UIUtils.SetLabelText(self.UITemplateTitlePanel.lab_Title, Const_IDS.IDS_PlotReview_Title) -- 打开界面时停止自动寻路 防止抽卡TimeLine和剧情重叠 NotSyncBattleSetter.StopAutoFightPathInTown() --停止现在的寻路 MDL.PlotReviewLibrary.PlotReviewInfoRequest() CTL.PlotReviewLibrary.ReceiveAllReward() self.curFirstSelectTab = nil self.curSecondSelectTab = nil self.curSelectedId = nil self.pointUIPool = {} -- 所有线的UI的池子 防止频繁创建 self.usedUIDic = {} -- 当前正在使用的UI,用于回收进池子 self.pointUIDic = {} -- 当前正在使用的节点 self.isOpenTab = false -- 是否展开二级页签 self:InitPanel() end function UIPlotReview:OnClosed() if self.curSecondSelectTab ~= nil then CTL.PlotReviewLibrary.CancelChapterRp(self.curSecondSelectTab) end end function UIPlotReview:OnBackButtonPressed() self:OnButtonClicked(self.UITemplateTitlePanel.btn_close) end function UIPlotReview:OnButtonClicked(comp) if comp == self.UITemplateTitlePanel.btn_close then self:CloseView(true) elseif comp == self.UITemplateTitlePanel.btn_Home then CTL.HomeMain.CloseViewBackHomeMain() elseif comp == self.UITemplateTitlePanel.btn_Info then UIManager.OpenView(Const_UI_Lua.UIEnum.UICommonNoteView, {id = LuaConst.NoteID.PlotReview}) else for id, itemObj in pairs(self.pointUIDic) do if comp == itemObj.btn_Icon then self:RefreshPointDesc(id) elseif comp == itemObj.btn_Select then self:RefreshPointDesc(id) elseif comp == itemObj.btn_Play then self:RefreshPointDesc(id) -- 如果一级页签是CG 则播放CG if self.curFirstSelectTab == CTL.PlotReviewLibrary.PlotReviewTabType.OpeningCinematic then CTL.PlotReviewLibrary.PlayCG(id) else -- 如果一级页签不是CG 则播放TimeLine CTL.PlotReviewLibrary.PlayTimeLine(self.curFirstSelectTab, self.curSecondSelectTab, id, self.toggle_Auto.isOn) end elseif comp == itemObj.btn_Lock then CTL.Tips.AddTipsMsg(UIUtils.GetLocalizedTxt(Const_IDS.IDS_GoldHeroActivity_ActivityLevel_LockHint1)) end end end end function UIPlotReview:OnCellInit(scrollRect, index, cellTable, data) if scrollRect == self.loop_Tab then if data.FirstType then -- 一级页签 UIUtils.SetLabelText(cellTable.txt_Name, Const_IDS[data.FirstType]) cellTable.SelectedState:SetState(self.curFirstSelectTab == data.ID and 1 or 0) cellTable.ArrowState:SetState(next(data.Include) and 0 or 1) if data.ID == CTL.PlotReviewLibrary.PlotReviewTabType.MainLine then UIUtils.SetActive(cellTable.img_RedDot, CTL.RedPoint.GetRedPointActive(CTL.RedPoint.RedPointKey.Library_PlotReview)) else UIUtils.SetActive(cellTable.img_RedDot, false) end else -- 二级页签 UIUtils.SetLabelText(cellTable.txt_Name, Const_IDS[data.SecondType]) cellTable.SelectedState:SetState(self.curSecondSelectTab == data.ID and 1 or 0) if self.curFirstSelectTab == CTL.PlotReviewLibrary.PlotReviewTabType.MainLine then UIUtils.SetActive(cellTable.img_RedDot, CTL.PlotReviewLibrary.CalculationChapterRp(data.ID)) else UIUtils.SetActive(cellTable.img_RedDot, false) end end end end function UIPlotReview:OnCellClicked(scrollRect, index, cellTable, target, data) if scrollRect == self.loop_Tab then if self.curSecondSelectTab ~= nil then CTL.PlotReviewLibrary.CancelChapterRp(self.curSecondSelectTab) end if data.FirstType then -- 一级页签 if self.curFirstSelectTab ~= data.ID or not self.isOpenTab then self.isOpenTab = true cellTable.obj_ArrowDirState:SetState(0) self.curSelectedId = nil self.curFirstSelectTab = data.ID if data.Include then self.curSecondSelectTab = data.Include[1] -- 默认选中第一个 end else self.isOpenTab = false cellTable.obj_ArrowDirState:SetState(1) end self:RefreshTabMenu() else -- 二级页签 if self.curSecondSelectTab ~= data.ID then self.curSelectedId = nil self.curSecondSelectTab = data.ID self:RefreshTabMenu() end end self:RefreshPlotReviewMap() self:SetMapSelectedPosition() end end -------------------- function UIPlotReview:InitPanel() local selectState = CTL.PlotReviewLibrary.GetSelectState() self.curFirstSelectTab = selectState.firstSelectTab self.curSecondSelectTab = selectState.secondSelectTab if self.curSecondSelectTab then self.isOpenTab = true end self:RefreshTabMenu() if self.curFirstSelectTab == nil and self.curSecondSelectTab == nil then -- 默认选择一级页签的第一个页签 self.loop_Tab:SelectIndex(0) else self:RefreshPlotReviewMap() end -- 连续播放默认是关闭状态 self.toggle_Auto.isOn = false self:RefreshPointDesc(selectState.selectId) self:SetMapSelectedPosition() CTL.PlotReviewLibrary.SetSelectState(nil, nil, nil) end function UIPlotReview:RefreshTabMenu() if self.loop_Tab.Count > 0 then self.loop_Tab:ClearCells() end for _, firstTabData in DataSheetManager.PlotReviewType1:GetEnumerator() do -- CG页签需要判断是否已经下载完分包 if firstTabData.ID == CTL.PlotReviewLibrary.PlotReviewTabType.OpeningCinematic then if CTL.HotFix.Get_IfAllDownload() then self.loop_Tab:AddData(firstTabData, 0) end else self.loop_Tab:AddData(firstTabData, 0) if self.curFirstSelectTab == firstTabData.ID and self.isOpenTab then for _, secondTabID in ipairs(firstTabData.Include) do local secondTabData = DataSheetManager.PlotReviewType2:GetDataByID(secondTabID) if secondTabData then self.loop_Tab:AddData(secondTabData, 1) end end end end end end function UIPlotReview:RefreshPlotReviewMap() local lastPointData, pointData if self.curFirstSelectTab == CTL.PlotReviewLibrary.PlotReviewTabType.OpeningCinematic then -- 如果一级页签是CG 则直接使用一级页签获取头节点 pointData = MDL.PlotReviewLibrary.GetHeadPointData(self.curFirstSelectTab) local firstTabData = DataSheetManager.PlotReviewType1:GetDataByID(self.curFirstSelectTab) UIUtils.SetLabelText(self.txt_Chapter, Const_IDS[firstTabData.FirstType]) UIUtils.SetActive(self.group_Auto, false) else -- 如果一级页签不是CG 则使用二级页签获取 pointData = MDL.PlotReviewLibrary.GetHeadPointData(self.curSecondSelectTab) local secondTabData = DataSheetManager.PlotReviewType2:GetDataByID(self.curSecondSelectTab) UIUtils.SetLabelText(self.txt_Chapter, Const_IDS[secondTabData.SecondType]) UIUtils.SetActive(self.group_Auto, true) end self:RecycleLineUI() -- 回收全部的UI进池子 并 清空正在使用的节点 if pointData then self:InitOneLine(self.Content.gameObject.transform, pointData, true) end -- 设置 Content 的大小滑动范围 local left, top, right, down = 0, 0, 0, 0 for _, uiList in pairs(self.usedUIDic) do for _, itemObj in ipairs(uiList) do local localPosX, localPosY = itemObj.gameObject.transform:GetLocalPosition() local sizeDeltaW, sizeDeltaH = itemObj.gameObject.transform:GetSizeDelta() -- 找到Top local newTop = localPosY + sizeDeltaH / 2 if newTop > top then top = newTop end -- 找到Down local newDown = localPosY - sizeDeltaH / 2 if newDown < down then down = newDown - 100 end -- 额外减 100 是为了预留一点额外的滑动范围 -- 找到Right local newRight = localPosX + sizeDeltaW if newRight > right then right = newRight + 100 end -- 额外加 100 是为了预留一点额外的滑动范围 end end self.Content.gameObject.transform:SetSizeDelta(right - left, top - down) -- 刷新一下选中 self:RefreshPointDesc(self.curSelectedId) end function UIPlotReview:RefreshAllRp() self:RefreshTabMenu() self:RefreshPlotReviewMap() end function UIPlotReview:RefreshPointDesc(id) self.curSelectedId = id local isSuccess, pointData = DataSheetManager.PlotReviewData:TryGetDataByID(self.curSelectedId) if isSuccess then UIUtils.SetLabelText(self.txt_ChapterInfo, Const_IDS[pointData.PlotDesc]) else UIUtils.SetLabel(self.txt_ChapterInfo, "") end -- 设置选中状态 for selectId, itemObj in pairs(self.pointUIDic) do if selectId == self.curSelectedId then UIUtils.SetActive(itemObj.img_Selected, true) else UIUtils.SetActive(itemObj.img_Selected, false) end end end function UIPlotReview:SetMapSelectedPosition() for selectId, itemObj in pairs(self.pointUIDic) do if selectId == self.curSelectedId then local posX, posY, posZ = itemObj.gameObject.transform:GetLocalPosition() self.Content.gameObject.transform:SetAnchoredPosition(posX * -1, posY * -1, posZ) return end end self.Content.gameObject.transform:SetAnchoredPosition(0, 0, 0) end function UIPlotReview:InitOneLine(pointPosNode, pointData, isShort) local itemObj = self:GetPointUIByType(isShort and LineAndPointType.ShortOneLine or LineAndPointType.LongOneLine) itemObj.gameObject.transform:SetPosition(pointPosNode:GetPosition()) self:SetPointUI(itemObj, pointData) end function UIPlotReview:InitOneToDownLine(pointPosNode, pointData, isShort) local itemObj = self:GetPointUIByType(isShort and LineAndPointType.ShortOneToDownLine or LineAndPointType.LongOneToDownLine) itemObj.gameObject.transform:SetPosition(pointPosNode:GetPosition()) self:SetPointUI(itemObj, pointData) end function UIPlotReview:InitOneToUpLine(pointPosNode, pointData, isShort) local itemObj = self:GetPointUIByType(isShort and LineAndPointType.ShortOneToUpLine or LineAndPointType.LongOneToUpLine) itemObj.gameObject.transform:SetPosition(pointPosNode:GetPosition()) self:SetPointUI(itemObj, pointData) end function UIPlotReview:SetPointUI(lineItemObj, pointData) -- 如果当前节点没有被使用过 在进行数据的初始化 if not self.pointUIDic[pointData.ID] then local itemObj if pointData.PlotTimeline > 0 or not string.isNilOrEmpty(pointData.CGName) then itemObj = self:GetPointUIByType(LineAndPointType.HighPointRoot) itemObj.gameObject.transform:SetPosition(lineItemObj.obj_HighPos:GetPosition()) -- 设置新字本地化图片 UIUtils.SetLocalizationImage(itemObj.img_New, "zr_msz_new.png") itemObj.img_New:SetNativeSize() -- 设置图片和名字 if not string.isNilOrEmpty(pointData.PlotPic) then UIUtils.SetImageByAssetBundle(itemObj.img_Level, pointData.PlotPic) end UIUtils.SetLabelText(itemObj.lab_Level, Const_IDS[pointData.PlotName]) if pointData.PlotType == CTL.PlotReviewLibrary.PlotReviewTabType.OpeningCinematic then itemObj.state_Img:SetState(1) lineItemObj.state_Line:SetState(1) UIUtils.SetActive(itemObj.img_Reward, false) elseif self.curFirstSelectTab == CTL.PlotReviewLibrary.PlotReviewTabType.MainLine then -- 主线剧情节点显示 local unlockLevelId = MDL.LevelSelect.GetUnlockLevelIdByDifficult(MDL.LevelSelect.Difficult.Normal) if pointData.BarrierID <= unlockLevelId then itemObj.state_Img:SetState(1) lineItemObj.state_Line:SetState(1) UIUtils.SetActive(itemObj.img_Reward, false) else itemObj.state_Img:SetState(0) lineItemObj.state_Line:SetState(0) end elseif self.curFirstSelectTab == CTL.PlotReviewLibrary.PlotReviewTabType.GoldenHero then -- 列传节点显示 if MDL.PlotReviewLibrary.GetDoneUniqueState(pointData.BarrierID) then itemObj.state_Img:SetState(1) lineItemObj.state_Line:SetState(1) UIUtils.SetActive(itemObj.img_Reward, false) else itemObj.state_Img:SetState(0) lineItemObj.state_Line:SetState(0) end end -- 设置是否是新 if itemObj.state_Img.CurState == 1 then if self.curFirstSelectTab == CTL.PlotReviewLibrary.PlotReviewTabType.MainLine then local newDataDic = PersistentData.PlayerData:Get(CTL.PlotReviewLibrary.PlotReview_NewData, {}) if not newDataDic[pointData.ID] then UIUtils.SetActive(itemObj.img_New, true) else UIUtils.SetActive(itemObj.img_New, false) end else UIUtils.SetActive(itemObj.img_New, false) end end -- 加载接下来的线 self:HelperInitNextLine(itemObj.obj_NextNodePos, pointData) else itemObj = self:GetPointUIByType(LineAndPointType.LowPointRoot) itemObj.gameObject.transform:SetPosition(lineItemObj.obj_LowPos:GetPosition()) if not string.isNilOrEmpty(pointData.PlotName) then UIUtils.SetActive(itemObj.img_TxtBg, true) UIUtils.SetLabelText(itemObj.lab_Task, Const_IDS[pointData.PlotName]) else UIUtils.SetActive(itemObj.img_TxtBg, false) end -- 加载接下来的线 self:HelperInitNextLine(itemObj.obj_NextNodePos, pointData) end self.pointUIDic[pointData.ID] = itemObj end end function UIPlotReview:HelperInitNextLine(nextNodePos, pointData) local isShort = pointData.PlotTimeline > 0 or not string.isNilOrEmpty(pointData.CGName) if #pointData.PostPoint == 1 then local nextPointData = DataSheetManager.PlotReviewData:GetDataByID(pointData.PostPoint[1]) if nextPointData then if #nextPointData.PrePoint == 1 then -- 一对一节点 使用单条横线连接 self:InitOneLine(nextNodePos, nextPointData, isShort) elseif #nextPointData.PrePoint == 2 then -- 多对一节点 使用折线连接 if nextPointData.PrePoint[1] == pointData.ID then self:InitOneToDownLine(nextNodePos, nextPointData, isShort) elseif nextPointData.PrePoint[2] == pointData.ID then self:InitOneToUpLine(nextNodePos, nextPointData, isShort) end end end elseif #pointData.PostPoint == 2 then local isSuccess1, nextUpPointData = DataSheetManager.PlotReviewData:TryGetDataByID(pointData.PostPoint[1]) if isSuccess1 then if #nextUpPointData.PrePoint == 1 then self:InitOneToUpLine(nextNodePos, nextUpPointData, isShort) elseif #nextUpPointData.PrePoint == 2 then if nextUpPointData.PrePoint[1] == pointData.ID then self:InitOneToDownLine(nextNodePos, nextUpPointData, isShort) elseif nextUpPointData.PrePoint[2] == pointData.ID then self:InitOneToUpLine(nextNodePos, nextUpPointData, isShort) end end end local isSuccess2, nextDownPointData = DataSheetManager.PlotReviewData:TryGetDataByID(pointData.PostPoint[2]) if isSuccess2 then if #nextDownPointData.PrePoint == 1 then self:InitOneToDownLine(nextNodePos, nextDownPointData, isShort) elseif #nextDownPointData.PrePoint == 2 then if nextDownPointData.PrePoint[1] == pointData.ID then self:InitOneToDownLine(nextNodePos, nextDownPointData, isShort) elseif nextDownPointData.PrePoint[2] == pointData.ID then self:InitOneToUpLine(nextNodePos, nextDownPointData, isShort) end end end end end function UIPlotReview:GetPointUIByType(lineAndPointType) local uiList = self.pointUIPool[lineAndPointType] local itemObj if uiList and next(uiList) then itemObj = table.remove(uiList) itemObj.gameObject.transform:SetParent(self.Content.gameObject.transform, true) else if lineAndPointType == LineAndPointType.ShortOneLine then itemObj = self:InstantiateCollection(self.Content, self.template_ShortOneLine.gameObject) elseif lineAndPointType == LineAndPointType.LongOneLine then itemObj = self:InstantiateCollection(self.Content, self.template_LongOneLine.gameObject) elseif lineAndPointType == LineAndPointType.ShortOneToUpLine then itemObj = self:InstantiateCollection(self.Content, self.template_ShortOneToUpLine.gameObject) elseif lineAndPointType == LineAndPointType.LongOneToUpLine then itemObj = self:InstantiateCollection(self.Content, self.template_LongOneToUpLine.gameObject) elseif lineAndPointType == LineAndPointType.ShortOneToDownLine then itemObj = self:InstantiateCollection(self.Content, self.template_ShortOneToDownLine.gameObject) elseif lineAndPointType == LineAndPointType.LongOneToDownLine then itemObj = self:InstantiateCollection(self.Content, self.template_LongOneToDownLine.gameObject) elseif lineAndPointType == LineAndPointType.LowPointRoot then itemObj = self:InstantiateCollection(self.Content, self.template_LowRoot.gameObject) elseif lineAndPointType == LineAndPointType.HighPointRoot then itemObj = self:InstantiateCollection(self.Content, self.template_HighRoot.gameObject) end UIUtils.SetActive(itemObj.gameObject, true) end local uiList = self.usedUIDic[lineAndPointType] if not uiList then uiList = {} self.usedUIDic[lineAndPointType] = uiList end table.insert(uiList, itemObj) return itemObj end -- 将已经创建的节点回收进池子(减少频繁创建) function UIPlotReview:RecycleLineUI() for lineAndPointType, uiList in pairs(self.usedUIDic) do for _, itemObj in ipairs(uiList) do itemObj.gameObject.transform:SetParent(self.templatePool, true) local poolUIList = self.pointUIPool[lineAndPointType] if not poolUIList then poolUIList = {} self.pointUIPool[lineAndPointType] = poolUIList end table.insert(poolUIList, itemObj) end end table.clear(self.usedUIDic) table.clear(self.pointUIDic) end function UIPlotReview:EndCG() self:RefreshPlotReviewMap() CTL.PlotReviewLibrary.ResetLevelSound() end return UIPlotReview