using System.Collections.Generic;
|
using UnityEngine;
|
using UnityEngine.UI;
|
using DG.Tweening;
|
using System.Linq;
|
using EnhancedUI.EnhancedScroller;
|
|
public class HeroDebutCallWin : UIBase
|
{
|
[SerializeField] ImageEx bgImage;
|
[SerializeField] RectTransform changeRect;
|
[SerializeField] UIEffectPlayer changeUIEffect;
|
|
[SerializeField] OwnItemCell ownItemCell;
|
[SerializeField] ButtonEx closeBtn;
|
[SerializeField] Toggle skipToggle;
|
[SerializeField] HeroDebutCallButton xbButton1;
|
[SerializeField] HeroDebutCallButton xbButton10;
|
[SerializeField] TextEx resMoneyCallCntText;
|
[SerializeField] GradientText 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] HeroDebutCallBubbleCell[] bubbleCell;
|
|
[SerializeField] float modleSize = 1f;
|
HeroDebutManager manager => HeroDebutManager.Instance;
|
|
protected override void InitComponent()
|
{
|
closeButton.SetListener(CloseWindow);
|
shopButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutShopWin>());
|
giftButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutGiftWin>());
|
changeHeroButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallChangeWin>());
|
rankButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutRankWin>());
|
rateButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallRateWin>());
|
historyButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallHistoryWin>());
|
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;
|
|
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;
|
}
|
|
|
|
// 1. 在类中声明一个全局的 Sequence 变量,用于统一管控动画
|
private Sequence heroAnimSeq;
|
|
private void OnUpdateHeroAppearPlayerInfoEvent(int actNum)
|
{
|
changeRect.SetActive(false);
|
|
// 2. 彻底杀死之前的 Sequence,防止快速连点造成内部 Tween 复用错乱
|
if (heroAnimSeq != null)
|
{
|
heroAnimSeq.Kill();
|
heroAnimSeq = null;
|
}
|
|
// 刷新界面数据和英雄模型(这里面会调用 lhController.Create)
|
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; // 默认缩放
|
// 检查是否有配置专属的立绘缩放参数(TachieParam[2])
|
if (skinConfig != null && skinConfig.TachieParam != null && skinConfig.TachieParam.Length == 4)
|
{
|
baseScaleValue = skinConfig.TachieParam[2];
|
}
|
|
Vector3 baseScale = Vector3.one * baseScaleValue;
|
|
// 【强制复位!】解决 UIHeroController 内部 return 导致的缩放未复位问题
|
targetTrans.localScale = baseScale;
|
|
// 获取或添加 CanvasGroup 用于透明度控制
|
CanvasGroup cg = lhController.GetComponent<CanvasGroup>();
|
if (cg == null) cg = lhController.gameObject.AddComponent<CanvasGroup>();
|
cg.DOKill();
|
cg.alpha = 0.8f;
|
|
changeUIEffect.Play();
|
|
// 4. 创建新的 Sequence 并赋值给成员变量
|
heroAnimSeq = DOTween.Sequence();
|
|
// 缩放动画基于正确的 baseScale 进行计算(变大1.1倍后再还原)
|
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));
|
|
// 动画完成后显示 changeRect,并清空引用
|
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(HeroDebutRedPointType.Shop);
|
giftRedpoint.redpointId = manager.GetRedPointId(HeroDebutRedPointType.Gift);
|
}
|
|
private void OnClickPreview()
|
{
|
if (heroConfig == null) return;
|
HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
|
UIManager.Instance.OpenWindow<HeroBestBaseWin>();
|
}
|
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 = ActHeroAppearArtConfig.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;
|
|
bgImage.SetSprite(artConfig.MainBgImage);
|
|
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 = 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<HeroDebutGameRec> list;
|
void OnRefreshCell(ScrollerDataType type, CellView cell)
|
{
|
var _cell = cell as HeroDebutCallHistoryOutCell;
|
_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;
|
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;
|
}
|
|
currentScrollerIndex++;
|
// 在 Loop 模式下进行平滑跳转
|
scroller.m_Scorller.JumpToDataIndex(
|
currentScrollerIndex % list.Count,
|
tweenType: EnhancedScroller.TweenType.easeInOutQuad,
|
tweenTime: 0.5f);
|
}
|
}
|