using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; using System.Linq; using EnhancedUI.EnhancedScroller; public class HeroReturnCallWin : UIBase { [SerializeField] RawImage chooseHeroBgImage; [SerializeField] ButtonEx chooseHeroButton; [SerializeField] ImageEx chooseHeroImage1; [SerializeField] ImageEx chooseHeroImage2; [SerializeField] Transform lhTransform; [SerializeField] Transform heroCallTransform; [SerializeField] Transform topTransform; [SerializeField] Transform heroInfoTransform; [SerializeField] ImageEx bgImage; [SerializeField] RectTransform changeRect; [SerializeField] UIEffectPlayer changeUIEffect; [SerializeField] OwnItemCell ownItemCell; [SerializeField] ButtonEx closeBtn; [SerializeField] Toggle skipToggle; [SerializeField] HeroReturnCallButton xbButton1; [SerializeField] HeroReturnCallButton xbButton10; [SerializeField] TextEx resMoneyCallCntText; [SerializeField] TextEx nextBigAwardCntText; [SerializeField] GradientText heroQualityText; [SerializeField] GradientText heroNameText; [SerializeField] TextEx timeText; [SerializeField] TextEx nameText; [SerializeField] TextEx descText; [SerializeField] ImageEx countryImage; [SerializeField] ImageEx jobImage; [SerializeField] ButtonEx changeHeroButton;//更换英雄 [SerializeField] ButtonEx previewButton;//满级预览 [SerializeField] ButtonEx closeButton; [SerializeField] ButtonEx shopButton; // 兑换商店 [SerializeField] RedpointBehaviour shopRedpoint; [SerializeField] ButtonEx giftButton; // 皇权礼包 [SerializeField] RedpointBehaviour giftRedpoint; [SerializeField] ButtonEx rankButton; [SerializeField] TextEx[] top3NameText; [SerializeField] TextEx rankTipText; [SerializeField] ButtonEx rateButton; [SerializeField] ScrollerController scroller; [SerializeField] ButtonEx historyButton; [SerializeField] UIHeroController lhController; [SerializeField] UIHeroController uiHeroController; [SerializeField] HeroReturnCallBubbleCell[] bubbleCell; [SerializeField] float modleSize = 1f; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); shopButton.SetListener(() => UIManager.Instance.OpenWindow()); giftButton.SetListener(() => UIManager.Instance.OpenWindow()); changeHeroButton.SetListener(() => UIManager.Instance.OpenWindow()); rankButton.SetListener(() => UIManager.Instance.OpenWindow()); rateButton.SetListener(() => UIManager.Instance.OpenWindow()); historyButton.SetListener(() => UIManager.Instance.OpenWindow()); chooseHeroButton.SetListener(() => UIManager.Instance.OpenWindow()); previewButton.SetListener(OnClickPreview); skipToggle.AddListener((value) => { manager.SaveCallSkipData(config.CfgID, act.startDate, act.endDate, value); }); } protected override void OnPreOpen() { scroller.lockType = EnhanceLockType.LockVerticalBottom; RankModel.Instance.ResetQueryParam(); RankModel.Instance.QueryRankByPage(manager.sendRankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID, groupValue1: manager.actNum); HappyXBModel.Instance.RefreshXBTypeInfoAct += OnRefreshXBTypeInfoAct; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; RankModel.Instance.onRankRefresh += OnRankRefresh; PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefresh; PackManager.Instance.RefreshItemEvent += RefreshItemEvent; scroller.OnRefreshCell += OnRefreshCell; manager.OnUpdateGameRecInfo += OnUpdateGameRecInfo; manager.OnUpdateHeroAppearPlayerInfoEvent += OnUpdateHeroAppearPlayerInfoEvent; if (manager.isSendFirst) { act = manager.GetOperationHeroAppearInfo(); if (act == null) return; config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int treasureType = config.ActTreasureType; manager.SendViewGameRecPack(treasureType); } InitRedpoint(); CreateScroller(); Display(); } protected override void OnPreClose() { HappyXBModel.Instance.RefreshXBTypeInfoAct -= OnRefreshXBTypeInfoAct; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; RankModel.Instance.onRankRefresh -= OnRankRefresh; PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefresh; PackManager.Instance.RefreshItemEvent -= RefreshItemEvent; scroller.OnRefreshCell -= OnRefreshCell; manager.OnUpdateGameRecInfo -= OnUpdateGameRecInfo; manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent; } private Sequence heroAnimSeq; private void OnUpdateHeroAppearPlayerInfoEvent() { changeRect.SetActive(false); if (heroAnimSeq != null) { heroAnimSeq.Kill(); heroAnimSeq = null; } Display(); Transform targetTrans = lhController.transform; // 停止 Transform 上可能残留的单独动画 targetTrans.DOKill(); int heroID = manager.GetCurrentDisplayCallHeroId(); int skinID = manager.GetDefaultSkinID(heroID); var skinConfig = HeroSkinConfig.Get(skinID); float baseScaleValue = 1f; // 默认缩放 if (skinConfig != null && skinConfig.TachieParam != null && skinConfig.TachieParam.Length == 4) { baseScaleValue = skinConfig.TachieParam[2]; } Vector3 baseScale = Vector3.one * baseScaleValue; targetTrans.localScale = baseScale; CanvasGroup cg = lhController.GetComponent(); if (cg == null) cg = lhController.gameObject.AddComponent(); cg.DOKill(); cg.alpha = 0.8f; changeUIEffect.Play(); heroAnimSeq = DOTween.Sequence(); heroAnimSeq.Append(targetTrans.DOScale(baseScale * 1.1f, 0.3f).SetEase(Ease.OutQuad)); heroAnimSeq.Append(targetTrans.DOScale(baseScale, 0.3f).SetEase(Ease.InQuad)); heroAnimSeq.Join(cg.DOFade(1f, 0.3f).SetEase(Ease.Linear)); heroAnimSeq.OnComplete(() => { changeRect.SetActive(true); heroAnimSeq = null; }); } private void OnUpdateGameRecInfo() { CreateScroller(); } public void RefreshItemEvent(PackType packType, int index, int itemID) { if (packType != PackType.Item && treasureSetConfig?.CostItemID != itemID) return; Display(); } private void PlayerDataRefresh(PlayerDataType type) { if (type != PlayerDataType.Gold) return; Display(); } private void OnRankRefresh(int type) { if (type != manager.sendRankType) return; ShowTop3(); } private void OnSecondEvent() { manager.GetActTimeStr(timeText); } private void OnRefreshXBTypeInfoAct() { Display(); } public void InitRedpoint() { shopRedpoint.redpointId = manager.GetRedPointId(HeroReturnRedPointType.Shop); giftRedpoint.redpointId = manager.GetRedPointId(HeroReturnRedPointType.Gift); } private void OnClickPreview() { if (heroConfig == null) return; HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID; UIManager.Instance.OpenWindow(); } OperationHeroAppearInfo act; ActHeroAppearConfig config; HeroConfig heroConfig; TreasureSetConfig treasureSetConfig; XBTypeInfo xbTypeInfo; private void Display() { act = manager.GetOperationHeroAppearInfo(); if (act == null) return; config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int heroID = manager.GetCurrentDisplayCallHeroId(); heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return; int skinID = manager.GetDefaultSkinID(heroID); var skinConfig = HeroSkinConfig.Get(skinID); if (skinConfig == null) return; var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null || artConfig.CallBubbleItems == null) return; int treasureType = config.ActTreasureType; treasureSetConfig = TreasureSetConfig.Get(treasureType); if (treasureSetConfig == null) return; xbTypeInfo = HappyXBModel.Instance.GetXBInfoByType(treasureType); if (xbTypeInfo == null) return; bool canChooseHero = !manager.IsSingleHero(act); bool isChooseHero = manager.LoadCallChooseHeroStateKey(act); chooseHeroBgImage.SetActive(canChooseHero && !isChooseHero); chooseHeroButton.SetActive(canChooseHero && !isChooseHero); chooseHeroImage1.SetActive(canChooseHero && !isChooseHero); chooseHeroImage2.SetActive(canChooseHero && !isChooseHero); lhTransform.SetActive(!canChooseHero || isChooseHero); heroCallTransform.SetActive(!canChooseHero || isChooseHero); topTransform.SetActive(!canChooseHero || isChooseHero); heroInfoTransform.SetActive(!canChooseHero || isChooseHero); bgImage.SetSprite(StringUtility.Concat("HeroReturnCallBG_", heroID.ToString())); lhController.Create(skinID, 1, motionName: "", isLh: true); uiHeroController.Create(skinID, modleSize); uiHeroController.transform.localScale = new Vector3(modleSize, modleSize, modleSize); ownItemCell.itemID = treasureSetConfig.CostItemID; skipToggle.isOn = manager.LoadCallSkipData(config.CfgID, act.startDate, act.endDate); xbButton1.Display(config.ActTreasureType, 0); xbButton10.Display(config.ActTreasureType, 1); resMoneyCallCntText.text = Language.Get("HeroDebut24", Mathf.Max(treasureSetConfig.DailyMaxCountMoney - xbTypeInfo.treasureCountTodayGold, 0)); var needCount = GetNextXBCountForBigAward(treasureType); nextBigAwardCntText.text = Language.Get("HeroDebut08", needCount.ToString()); heroQualityText.text = Language.Get($"heroCallQaulity{heroConfig.Quality}"); manager.SetheroQaulityColor(heroQualityText, heroConfig.Quality); nameText.text = heroConfig.Name; nameText.color = UIHelper.GetUIColorByFunc(heroConfig.Quality); descText.text = heroConfig.Desc; countryImage.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country)); jobImage.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class)); heroNameText.text = heroConfig.Name; manager.SetGradientTextColor(heroNameText, artConfig.HeroNameColor); for (int i = 0; i < bubbleCell.Length; i++) { if (i < artConfig.CallBubbleItems.Length) { bubbleCell[i].SetActive(true); bubbleCell[i].Display(artConfig.CallBubbleItems[i][0], artConfig.CallBubbleItems[i][1]); } else { bubbleCell[i].SetActive(false); } } ShowTop3(); OnSecondEvent(); } public int GetNextXBCountForBigAward(int type) { XBTypeInfo typeInfo = HappyXBModel.Instance.GetXBInfoByType(type); if (typeInfo == null) return 0; var xbConfig = HappyXBModel.Instance.GetXBItemConfigByType(type); var luckList = xbConfig.LuckyItemRateInfo.Keys.ToList(); luckList.Sort(); for (int i = 0; i < luckList.Count; i++) { var luckyValue = typeInfo.luckValue; if (luckyValue < luckList[i]) { return luckList[i] - luckyValue; } } return 0; } void ShowTop3() { for (int i = 0; i < top3NameText.Length; i++) { var rankData = RankModel.Instance.GetRankDataByRank(manager.loadRankType, i + 1); top3NameText[i].text = rankData == null ? Language.Get("L1124") : rankData.name1; } int billTempID = config.BillTempID; rankTipText.text = Language.Get("HeroDebut27", ActBillboardAwardConfig.GetTop3MinCalNeedValue(billTempID)); } public List list; void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnCallHistoryOutCell; _cell.Display(cell.index, list); } float autoScrollInterval = 2f; private float autoScrollTimer = 0f; private int currentScrollerIndex = 0; private bool isScrollerReady = false; // 判定标志 void CreateScroller() { list = manager.GetGameRecList(); scroller.Refresh(); int listCount = list?.Count ?? 0; historyButton.SetActive(listCount > 0); if (list != null) { for (int i = 0; i < listCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } } bool canScroll = listCount > 4;// 只有数量 > 4 时才开启 Loop 和计时器 scroller.m_Scorller.Loop = canScroll; isScrollerReady = canScroll; scroller.vertical = false; scroller.horizontal = false; scroller.Restart(); // 如果是循环模式,确保初始位置正确 if (canScroll) { scroller.m_Scorller.JumpToDataIndex(0, tweenType: EnhancedScroller.TweenType.immediate); } autoScrollTimer = 0f; currentScrollerIndex = 0; } private void LateUpdate() { // 只有在数据就绪且超过 4 个时,才执行计时逻辑 if (isScrollerReady) { autoScrollTimer += Time.deltaTime; if (autoScrollTimer >= autoScrollInterval) { autoScrollTimer = 0f; AutoScrollNext(); } } } private void AutoScrollNext() { if (list?.Count <= 4) { isScrollerReady = false; return; } // 检查 scroller 的 GameObject 是否处于激活状态 if (scroller == null || scroller.m_Scorller == null || !scroller.m_Scorller.gameObject.activeInHierarchy) { return; } currentScrollerIndex++; // 在 Loop 模式下进行平滑跳转 scroller.m_Scorller.JumpToDataIndex( currentScrollerIndex % list.Count, tweenType: EnhancedScroller.TweenType.easeInOutQuad, tweenTime: 0.5f); } }