Main/Config/ConfigManager.cs
@@ -43,6 +43,8 @@ typeof(ActHeroAppearConfig), typeof(ActHeroAppearSkinArtConfig), typeof(ActHeroAppearStarConfig), typeof(ActHeroReturnArtConfig), typeof(ActHeroReturnSkinArtConfig), typeof(ActLunhuidianTypeConfig), typeof(ActSignAwardConfig), typeof(ADAwardConfig), @@ -278,6 +280,10 @@ ClearConfigDictionary<ActHeroAppearSkinArtConfig>(); // 清空 ActHeroAppearStarConfig 字典 ClearConfigDictionary<ActHeroAppearStarConfig>(); // 清空 ActHeroReturnArtConfig 字典 ClearConfigDictionary<ActHeroReturnArtConfig>(); // 清空 ActHeroReturnSkinArtConfig 字典 ClearConfigDictionary<ActHeroReturnSkinArtConfig>(); // 清空 ActLunhuidianTypeConfig 字典 ClearConfigDictionary<ActLunhuidianTypeConfig>(); // 清空 ActSignAwardConfig 字典 Main/Config/Configs/ActHeroAppearConfig.cs
@@ -1,6 +1,6 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: 2026年3月9日 // [ Date ]: Thursday, March 26, 2026 //-------------------------------------------------------- using System.Collections.Generic; @@ -17,6 +17,7 @@ } public int CfgID; public int ActNum; public int[] ActHeroIDList; public int ActTreasureType; public int StarGiftTempID; @@ -40,13 +41,15 @@ string[] tables = input.Split('\t'); int.TryParse(tables[0],out CfgID); if (tables[1].Contains("[")) int.TryParse(tables[1],out ActNum); if (tables[2].Contains("[")) { ActHeroIDList = JsonMapper.ToObject<int[]>(tables[1]); ActHeroIDList = JsonMapper.ToObject<int[]>(tables[2]); } else { string[] ActHeroIDListStringArray = tables[1].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); string[] ActHeroIDListStringArray = tables[2].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); ActHeroIDList = new int[ActHeroIDListStringArray.Length]; for (int i=0;i<ActHeroIDListStringArray.Length;i++) { @@ -54,17 +57,17 @@ } } int.TryParse(tables[2],out ActTreasureType); int.TryParse(tables[3],out ActTreasureType); int.TryParse(tables[3],out StarGiftTempID); int.TryParse(tables[4],out StarGiftTempID); if (tables[4].Contains("[")) if (tables[5].Contains("[")) { SkinCTGIDList = JsonMapper.ToObject<int[]>(tables[4]); SkinCTGIDList = JsonMapper.ToObject<int[]>(tables[5]); } else { string[] SkinCTGIDListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); string[] SkinCTGIDListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); SkinCTGIDList = new int[SkinCTGIDListStringArray.Length]; for (int i=0;i<SkinCTGIDListStringArray.Length;i++) { @@ -72,13 +75,13 @@ } } if (tables[5].Contains("[")) if (tables[6].Contains("[")) { GiftCTGIDList = JsonMapper.ToObject<int[]>(tables[5]); GiftCTGIDList = JsonMapper.ToObject<int[]>(tables[6]); } else { string[] GiftCTGIDListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); string[] GiftCTGIDListStringArray = tables[6].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); GiftCTGIDList = new int[GiftCTGIDListStringArray.Length]; for (int i=0;i<GiftCTGIDListStringArray.Length;i++) { @@ -86,15 +89,15 @@ } } int.TryParse(tables[6],out GiftShopType); int.TryParse(tables[7],out GiftShopType); int.TryParse(tables[7],out ExShopType); int.TryParse(tables[8],out ExShopType); int.TryParse(tables[8],out ExShopCostItemID); int.TryParse(tables[9],out ExShopCostItemID); int.TryParse(tables[9],out SignTempID); int.TryParse(tables[10],out SignTempID); int.TryParse(tables[10],out BillTempID); int.TryParse(tables[11],out BillTempID); } catch (Exception exception) { Main/Config/Configs/ActHeroAppearSkinArtConfig.cs
@@ -1,6 +1,6 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: 2026年3月11日 // [ Date ]: 2026年3月26日 //-------------------------------------------------------- using System.Collections.Generic; Main/Config/Configs/ActHeroReturnArtConfig.cs
New file @@ -0,0 +1,107 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: 2026年3月26日 //-------------------------------------------------------- using System.Collections.Generic; using System; using UnityEngine; using LitJson; public partial class ActHeroReturnArtConfig : ConfigBase<int, ActHeroReturnArtConfig> { static ActHeroReturnArtConfig() { // 访问过静态构造函数 visit = true; } public int HeroID; public int[][] HeroNameColor; public int[][] CallBubbleItems; public string EntryBgImage; public string EntryTitleText; public string PopBgImage; public string PopTitleBgImage; public string PopTitleImage; public string PopInfoBgImage; public int PopInfoBgUIEffectId; public string PopInfoText; public int[] PopInfoColor; public string MainBgImage; public string MainTitleImage; public int MainSkinID; public string StarUpHeroImage; public string GiftBgImage; public string GiftHeroImage; public string RankAwardHeroImage; public string CheckInBgImage; public override int LoadKey(string _key) { int key = GetKey(_key); return key; } public override void LoadConfig(string input) { try { string[] tables = input.Split('\t'); int.TryParse(tables[0],out HeroID); HeroNameColor = JsonMapper.ToObject<int[][]>(tables[1].Replace("(", "[").Replace(")", "]")); CallBubbleItems = JsonMapper.ToObject<int[][]>(tables[2].Replace("(", "[").Replace(")", "]")); EntryBgImage = tables[3]; EntryTitleText = tables[4]; PopBgImage = tables[5]; PopTitleBgImage = tables[6]; PopTitleImage = tables[7]; PopInfoBgImage = tables[8]; int.TryParse(tables[9],out PopInfoBgUIEffectId); PopInfoText = tables[10]; if (tables[11].Contains("[")) { PopInfoColor = JsonMapper.ToObject<int[]>(tables[11]); } else { string[] PopInfoColorStringArray = tables[11].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); PopInfoColor = new int[PopInfoColorStringArray.Length]; for (int i=0;i<PopInfoColorStringArray.Length;i++) { int.TryParse(PopInfoColorStringArray[i],out PopInfoColor[i]); } } MainBgImage = tables[12]; MainTitleImage = tables[13]; int.TryParse(tables[14],out MainSkinID); StarUpHeroImage = tables[15]; GiftBgImage = tables[16]; GiftHeroImage = tables[17]; RankAwardHeroImage = tables[18]; CheckInBgImage = tables[19]; } catch (Exception exception) { Debug.LogError(exception); } } } Main/Config/Configs/ActHeroReturnArtConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 010dfd3e7d7da104f8daef3fb34fd922 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/Configs/ActHeroReturnSkinArtConfig.cs
New file @@ -0,0 +1,56 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: Thursday, March 26, 2026 //-------------------------------------------------------- using System.Collections.Generic; using System; using UnityEngine; using LitJson; public partial class ActHeroReturnSkinArtConfig : ConfigBase<int, ActHeroReturnSkinArtConfig> { static ActHeroReturnSkinArtConfig() { // 访问过静态构造函数 visit = true; } public int SkinID; public string MainSkinBuyBgImage; public string BGImage; public string HeroNameImage; public string SkinInfoImage; public string AwardBGImage; public string TabInfoImage; public override int LoadKey(string _key) { int key = GetKey(_key); return key; } public override void LoadConfig(string input) { try { string[] tables = input.Split('\t'); int.TryParse(tables[0],out SkinID); MainSkinBuyBgImage = tables[1]; BGImage = tables[2]; HeroNameImage = tables[3]; SkinInfoImage = tables[4]; AwardBGImage = tables[5]; TabInfoImage = tables[6]; } catch (Exception exception) { Debug.LogError(exception); } } } Main/Config/Configs/ActHeroReturnSkinArtConfig.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 5a29cc75b87652c4d9357b05ef1853f5 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Config/PartialConfigs/ActHeroAppearConfig.cs
@@ -1,18 +1,40 @@ using System.Collections.Generic; using System.Linq; public partial class ActHeroAppearConfig : ConfigBase<int, ActHeroAppearConfig> { private static List<int> actTreasureTypeList; public static List<int> GetActTreasureTypeList() /// <summary> /// 武将登场的所有招募寻宝类型 /// </summary> private static HashSet<int> heroDebutActTreasureTypeList = new(); public static List<int> GetHeroDebutActTreasureTypeList() { if (actTreasureTypeList == null) if (heroDebutActTreasureTypeList.Count == 0) { actTreasureTypeList = new(); foreach (var item in GetValues()) { if (!actTreasureTypeList.Contains(item.ActTreasureType)) actTreasureTypeList.Add(item.ActTreasureType); if (item.ActNum != 10) continue; heroDebutActTreasureTypeList.Add(item.ActTreasureType); } } return actTreasureTypeList; return heroDebutActTreasureTypeList.ToList(); } /// <summary> /// 武将返场的所有招募寻宝类型 /// </summary> private static HashSet<int> heroReturnActTreasureTypeList = new(); public static List<int> GetHeroReturnActTreasureTypeList() { if (heroReturnActTreasureTypeList.Count == 0) { foreach (var item in GetValues()) { if (item.ActNum != 11) continue; heroReturnActTreasureTypeList.Add(item.ActTreasureType); } } return heroReturnActTreasureTypeList.ToList(); } } Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs
@@ -26,8 +26,40 @@ sortDict[starTempID] = list; } } public static List<int> GetHeroReturnAwardIndexSortList(int starTempID) { LoadSortList(); sortDict.TryGetValue(starTempID, out var list); public static List<int> GetAwardIndexSortList(int starTempID) List<int> res = new List<int>(); int heroId = HeroReturnManager.Instance.GetCurrentDisplayStarUpHeroId(); int nowStar = HeroReturnManager.Instance.GetNowHeroMaxStarCnt(heroId); for (int i = HeroReturnManager.Instance.seeArr.Length - 1; i >= 0; i--) { int[] info = HeroReturnManager.Instance.seeArr[i]; int needStar = info[0]; int seeStar = info[1]; if (nowStar >= needStar) { for (int j = 0; j < seeStar; j++) { if (j >= list.Count) continue; var config = GetConfig(starTempID, list[j]); if (config == null) continue; int tempStar = config.NeedStar; if (tempStar > seeStar) continue; res.Add(list[j]); } return res; } } return null; } public static List<int> GetHeroDebutAwardIndexSortList(int starTempID) { LoadSortList(); sortDict.TryGetValue(starTempID, out var list); Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA009_tagSCGameRecInfo.cs
@@ -10,5 +10,6 @@ ArenaManager.Instance.UpdateGameRecInfo(vNetData); HeroDebutManager.Instance.UpdateGameRecInfo(vNetData); QunyingManager.Instance.UpdateGameRecInfo(vNetData); HeroReturnManager.Instance.UpdateGameRecInfo(vNetData); } } Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs
@@ -10,5 +10,6 @@ base.Done(vNetPack); HAA22_tagSCActHeroAppearPlayerInfo vNetData = vNetPack as HAA22_tagSCActHeroAppearPlayerInfo; HeroDebutManager.Instance.UpdateHeroAppearPlayerInfo(vNetData); HeroReturnManager.Instance.UpdateHeroAppearPlayerInfo(vNetData); } } Main/Main.cs
@@ -112,6 +112,7 @@ managers.Add(GeneralActInfoManager.Instance); managers.Add(QunyingManager.Instance); managers.Add(ViewBuffManager.Instance); managers.Add(HeroReturnManager.Instance); foreach (var manager in managers) { Main/Manager/UIManager.cs
@@ -381,6 +381,43 @@ return false; } // 检查是否存在任何同层级sortingOrde大于我的窗口 public bool ExistAnySameLevelWinHigherSortingOrder(UILayer uiLayer, string excludeUIName) { int mySortingOrder = 0; if (uiDict.TryGetValue(excludeUIName, out List<UIBase> excludeList) && excludeList.Count > 0) { foreach (var ui in excludeList) { if (ui.IsActive()) { mySortingOrder = ui.GetSortingOrder(); break; } } } if (mySortingOrder == 0) return false; foreach (var uiList in uiDict.Values) { foreach (var ui in uiList) { if (!ui.IsActive()) continue; if (ui.uiName == excludeUIName) continue; if (ui.uiLayer != uiLayer) continue; if (ui.GetSortingOrder() > mySortingOrder) return true; } } return false; } // 获取指定类型的所有UI实例 public List<T> GetAllUI<T>() where T : UIBase Main/System/HappyXB/HappyXBModel.cs
@@ -182,14 +182,24 @@ { UIManager.Instance.OpenWindow<HeroCallResultWin>(); } return; } if (ActHeroAppearConfig.GetActTreasureTypeList().Contains(type)) if (ActHeroAppearConfig.GetHeroDebutActTreasureTypeList().Contains(type)) { if (!UIManager.Instance.IsOpened<HeroDebutCallResultWin>()) { UIManager.Instance.OpenWindow<HeroDebutCallResultWin>(); } return; } if (ActHeroAppearConfig.GetHeroReturnActTreasureTypeList().Contains(type)) { if (!UIManager.Instance.IsOpened<HeroReturnCallResultWin>()) { UIManager.Instance.OpenWindow<HeroReturnCallResultWin>(); } } } Main/System/HeroDebut/HeroDebutCallWin.cs
@@ -78,6 +78,7 @@ PackManager.Instance.RefreshItemEvent += RefreshItemEvent; scroller.OnRefreshCell += OnRefreshCell; manager.OnUpdateGameRecInfo += OnUpdateGameRecInfo; manager.OnUpdateHeroAppearPlayerInfoEvent += OnUpdateHeroAppearPlayerInfoEvent; if (manager.isSendFirst) { @@ -113,7 +114,7 @@ // 1. 在类中声明一个全局的 Sequence 变量,用于统一管控动画 private Sequence heroAnimSeq; private void OnUpdateHeroAppearPlayerInfoEvent(int actNum) private void OnUpdateHeroAppearPlayerInfoEvent() { changeRect.SetActive(false); Main/System/HeroDebut/HeroDebutManager.cs
@@ -77,9 +77,9 @@ private void OnBeforePlayerDataInitializeEventOnRelogin() { isSendFirst = true; starHeroIndexDict.Clear(); starHeroIndex = 0; callHeroIndex = 0; starFreeAwardDict.Clear(); callHeroIndexDict.Clear(); } private void OnPlayerLoginOk() @@ -243,22 +243,23 @@ OnNowCallChooseHeroIDChangeEvent?.Invoke(); } } public event Action<int> OnUpdateHeroAppearPlayerInfoEvent; public int starHeroIndex = 0; public int callHeroIndex = 0; //<升星计划选择的武将ID索引,升星计划免费奖励记录> Dictionary<int, uint> starFreeAwardDict = new(); public event Action OnUpdateHeroAppearPlayerInfoEvent; public void UpdateHeroAppearPlayerInfo(HAA22_tagSCActHeroAppearPlayerInfo vNetData) { if (vNetData == null) return; int actNum = vNetData.ActNum; starHeroIndexDict[actNum] = vNetData.StarHeroIndex; callHeroIndexDict[actNum] = vNetData.CallHeroIndex; if (vNetData.ActNum != this.actNum) return; if (!starFreeAwardDict.TryGetValue(actNum, out var dict)) { dict = new Dictionary<int, uint>(); starFreeAwardDict[actNum] = dict; } dict[vNetData.StarHeroIndex] = vNetData.StarFreeAward; int actNum = vNetData.ActNum; starHeroIndex = vNetData.StarHeroIndex; callHeroIndex = vNetData.CallHeroIndex; starFreeAwardDict[starHeroIndex] = vNetData.StarFreeAward; UpdateRedpoint(); OnUpdateHeroAppearPlayerInfoEvent?.Invoke(actNum); OnUpdateHeroAppearPlayerInfoEvent?.Invoke(); } public void SendHeroAppearStarHeroSelect(int actNum, int starHeroIndex) @@ -432,12 +433,6 @@ #region 升星计划 //<活动编号,升星计划选择的武将ID索引> public Dictionary<int, int> starHeroIndexDict = new(); //<活动编号,<升星计划选择的武将ID索引,升星计划免费奖励记录>> public Dictionary<int, Dictionary<int, uint>> starFreeAwardDict = new(); /// <summary> /// 当前升星计划选中的武将ID /// </summary> @@ -445,12 +440,11 @@ { var act = GetOperationHeroAppearInfo(); if (act == null) return 0; if (!starHeroIndexDict.TryGetValue(actNum, out int index)) return 0; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null || config.ActHeroIDList?.Length <= index) return 0; if (config == null || config.ActHeroIDList?.Length <= starHeroIndex) return 0; return config.ActHeroIDList[index]; return config.ActHeroIDList[starHeroIndex]; } private Dictionary<int, Dictionary<int, int[][]>> showHeroGiftItemInfoDict = new(); @@ -508,16 +502,14 @@ // 没获得武将本体不可领取 if (!HeroManager.Instance.HasHero(heroId))return 0; if (!starHeroIndexDict.TryGetValue(actNum, out int index)) return 0; if (IsStarUpFreeHave(index, config.AwardIndex)) return 2; if (IsStarUpFreeHave(starHeroIndex, config.AwardIndex)) return 2; if (IsHeroStarCntOk(heroConfig.HeroID, config.NeedStar)) return 1; return 0; } private bool IsStarUpFreeHave(int starHeroIndex, int awardIndex) { if (!starFreeAwardDict.TryGetValue(actNum, out var dict)) return false; if (!dict.TryGetValue(starHeroIndex, out uint freeAward)) return false; if (!starFreeAwardDict.TryGetValue(starHeroIndex, out uint freeAward)) return false; return ((freeAward >> awardIndex) & 1u) == 1u; } @@ -544,7 +536,7 @@ public bool TryGetStarUpStateIndex(int starGiftTempID, int tarState, out int index) { index = 0; var list = ActHeroAppearStarConfig.GetAwardIndexSortList(starGiftTempID); var list = ActHeroAppearStarConfig.GetHeroDebutAwardIndexSortList(starGiftTempID); if (list == null) return false; for (int i = 0; i < list.Count; i++) @@ -733,7 +725,7 @@ } private string GetCallSkipKey(int cfgID, OperationDate startDate, OperationDate endDate) { return string.Concat("HeroDebutManager_CallSkip_", cfgID, ToInt(startDate), ToInt(endDate), PlayerDatas.Instance.PlayerId); return string.Concat("HeroDebutManager_CallSkip_", cfgID, "_", ToInt(startDate), "_", ToInt(endDate), "_", PlayerDatas.Instance.PlayerId); } public bool LoadCallSkipData(int cfgID, OperationDate startDate, OperationDate endDate) @@ -746,9 +738,6 @@ LocalSave.SetBool(GetCallSkipKey(cfgID, startDate, endDate), value); } //<活动编号,招募选择的武将ID索引> public Dictionary<int, int> callHeroIndexDict = new(); /// <summary> /// 当前招募选中的武将ID /// </summary> @@ -756,12 +745,11 @@ { var act = GetOperationHeroAppearInfo(); if (act == null) return 0; if (!callHeroIndexDict.TryGetValue(actNum, out int index)) return 0; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null || config.ActHeroIDList?.Length <= index) return 0; if (config == null || config.ActHeroIDList?.Length <= callHeroIndex) return 0; return config.ActHeroIDList[index]; return config.ActHeroIDList[callHeroIndex]; } @@ -960,19 +948,10 @@ { return gameRecDict; } public List<HeroDebutGameRec> GetLastFourRecords() { if (gameRecDict == null || gameRecDict.Count == 0) return new List<HeroDebutGameRec>(); int count = gameRecDict.Count; int takeCount = Math.Min(4, count); return gameRecDict.GetRange(count - takeCount, takeCount); } public event Action OnUpdateGameRecInfo; public void UpdateGameRecInfo(HA009_tagSCGameRecInfo vNetData) { var act = GetOperationHeroAppearInfo(); if (act == null) return; Main/System/HeroDebut/HeroDebutStarUpWin.cs
@@ -44,7 +44,7 @@ manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent; } private void OnUpdateHeroAppearPlayerInfoEvent(int obj) private void OnUpdateHeroAppearPlayerInfoEvent() { scroller.m_Scorller.RefreshActiveCellViews(); } @@ -96,7 +96,7 @@ if (appearConfig == null || heroConfig == null) return; int starGiftTempID = appearConfig.StarGiftTempID; var list = ActHeroAppearStarConfig.GetAwardIndexSortList(starGiftTempID); var list = ActHeroAppearStarConfig.GetHeroDebutAwardIndexSortList(starGiftTempID); if (list == null) return; scroller.Refresh(); Main/System/HeroDebut/HeroDebutWin.cs
@@ -60,7 +60,7 @@ manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent; } private void OnUpdateHeroAppearPlayerInfoEvent(int obj) private void OnUpdateHeroAppearPlayerInfoEvent() { Display(); } Main/System/HeroReturn.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: ad40f79e4689d234fac9fc2f4d8be9a7 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallBubbleCell.cs
New file @@ -0,0 +1,23 @@ using UnityEngine; public class HeroReturnCallBubbleCell : MonoBehaviour { [SerializeField] ButtonEx clickButton; [SerializeField] ImageEx bgImage; [SerializeField] ImageEx iconImage; [SerializeField] TextEx countText; public void Display(int itemID, int count) { var config = ItemConfig.Get(itemID); if (config == null) return; bgImage.SetSprite($"HeroDebutCallBubbleBG{config.ItemColor}"); iconImage.SetItemSprite(itemID); iconImage.SetNativeSize(); countText.text = count.ToString(); clickButton.SetListener(() => ItemTipUtility.Show(itemID)); } } Main/System/HeroReturn/HeroReturnCallBubbleCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 10ed3265b0279984dbb79382f829567a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallButton.cs
New file @@ -0,0 +1,95 @@ using UnityEngine; public class HeroReturnCallButton : MonoBehaviour { [SerializeField] ButtonEx clickButton; [SerializeField] TextEx callText; [SerializeField] TextEx needText; [SerializeField] ImageEx needImage; HeroReturnManager manager => HeroReturnManager.Instance; HappyXBModel xbManager => HappyXBModel.Instance; int index; int type; int needCostItemCnt; long hasItemCnt; int needCostMoneyCnt; long moneyCount; public void Display(int treasureType, int index) { this.index = index; type = treasureType; var treasureSetConfig = TreasureSetConfig.Get(treasureType); if (treasureSetConfig == null) return; if (treasureSetConfig.TreasureCountList == null || treasureSetConfig.TreasureCountList.Length <= index) return; if (treasureSetConfig.CostItemCountList == null || treasureSetConfig.CostItemCountList.Length <= index) return; if (treasureSetConfig.CostMoneyList == null || treasureSetConfig.CostMoneyList.Length <= index) return; XBTypeInfo info = xbManager.GetXBInfoByType(treasureType); if (info == null) return; int treasureCnt = treasureSetConfig.TreasureCountList[index]; callText.text = Language.Get("HeroDebut23", treasureCnt); int dailyMaxCountMoney = treasureSetConfig.DailyMaxCountMoney; int nowMoneyCnt = info.treasureCountTodayGold; needCostMoneyCnt = treasureSetConfig.CostMoneyList[index]; moneyCount = UIHelper.GetMoneyCnt(treasureSetConfig.CostMoneyType); needCostItemCnt = treasureSetConfig.CostItemCountList[index]; hasItemCnt = PackManager.Instance.GetItemCountByID(PackType.Item, treasureSetConfig.CostItemID); // 物品不足 && 没超货币招募次数上限 if (hasItemCnt < needCostItemCnt && nowMoneyCnt + treasureCnt <= dailyMaxCountMoney) { DisplayByMoney(treasureSetConfig.CostMoneyType, needCostMoneyCnt, moneyCount); return; } DisplayByItem(treasureSetConfig.CostItemID, treasureCnt); } void DisplayByMoney(int moneyType, long needCostMoneyCnt, long moneyCount) { bool isEnough = moneyCount >= needCostMoneyCnt; needText.text = Language.Get("L1100", RichTextMsgReplaceConfig.GetRichReplace("MONEY", moneyType), UIHelper.AppendColor(!isEnough ? TextColType.Red : TextColType.LightGreen, needCostMoneyCnt.ToString())); needImage.SetIconWithMoneyType(moneyType); clickButton.SetListener(() => { if (!isEnough) { ItemTipUtility.ShowMoneyTip(moneyType, true); return; } HeroUIManager.Instance.selectCallType = (HappXBTitle)type; HeroUIManager.Instance.selectCallIndex = index; HappyXBModel.Instance.SendXBQuest(type, index, 0); }); } void DisplayByItem(int itemID, int count) { ItemConfig itemConfig = ItemConfig.Get(itemID); if (itemConfig == null) return; bool isEnough = hasItemCnt >= needCostItemCnt; needText.text = Language.Get("L1100", itemConfig.ItemName, UIHelper.AppendColor(!isEnough ? TextColType.Red : TextColType.LightGreen, count.ToString())); needImage.SetItemSprite(itemID); clickButton.SetListener(() => { if (!isEnough) { ItemTipUtility.Show(itemID, true); return; } HeroUIManager.Instance.selectCallType = (HappXBTitle)type; HeroUIManager.Instance.selectCallIndex = index; HappyXBModel.Instance.SendXBQuest(type, index, 2); }); } } Main/System/HeroReturn/HeroReturnCallButton.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: d55190ecb673d464f88f4ec0a5425732 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallChangeCell.cs
New file @@ -0,0 +1,33 @@ using UnityEngine; public class HeroReturnCallChangeCell : CellView { [SerializeField] HeroReturnCallChangeItem[] items; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int rowIndex) { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; var heroArr = config.ActHeroIDList; if (heroArr.IsNullOrEmpty()) return; for (int i = 0; i < items.Length; i++) { int index = rowIndex * HeroReturnCallChangeWin.rowCountMax + i; if (index < heroArr.Length) { items[i].SetActive(true); items[i].Display(index, heroArr, act.CfgID); } else { items[i].SetActive(false); } } } } Main/System/HeroReturn/HeroReturnCallChangeCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e0d034734cb56844cb0216e77c5b3440 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallChangeItem.cs
New file @@ -0,0 +1,41 @@ using UnityEngine; using UnityEngine.UI; public class HeroReturnCallChangeItem : MonoBehaviour { [SerializeField] HeroHeadBaseCell heroHeadBaseCell; [SerializeField] Image jobImg; [SerializeField] Text nameText; [SerializeField] Transform select; HeroReturnManager manager => HeroReturnManager.Instance; HeroConfig heroConfig; int index; public void Display(int index, int[] heroIds, int cfgId) { this.index = index; if (heroIds?.Length <= index) return; int heroId = heroIds[index]; heroConfig = HeroConfig.Get(heroId); if (heroConfig == null) return; int skinID = manager.GetDefaultSkinID(heroId); var heroSkinConfig = HeroSkinConfig.Get(skinID); if (heroSkinConfig == null) return; heroHeadBaseCell.Init(heroConfig.HeroID, skinID, 0, 0, 0, OnClick); nameText.text = heroConfig.Name; jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class)); bool isChoose = manager.nowCallChooseHeroID == heroId; select?.SetActive(isChoose); } public void OnClick() { if (heroConfig == null) return; manager.nowCallChooseHeroID = heroConfig.HeroID; } } Main/System/HeroReturn/HeroReturnCallChangeItem.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 0720ebe725ea61345a7c09406a98e96e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallChangeWin.cs
New file @@ -0,0 +1,100 @@ using UnityEngine; public class HeroReturnCallChangeWin : UIBase { [SerializeField] ScrollerController scroller; [SerializeField] ButtonEx closeButton; [SerializeField] ButtonEx okButton; [SerializeField] ButtonEx previewButton; [SerializeField] UIHeroController uiHeroController; public const int rowCountMax = 4; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); okButton.SetListener(() => { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; int index = manager.GetHeroIdIndex(act.CfgID, manager.nowCallChooseHeroID); if (index < 0) return; if (manager.GetCurrentDisplayCallHeroId() == manager.nowCallChooseHeroID) { SysNotifyMgr.Instance.ShowTip("HeroDebut01"); return; } manager.SnedHeroAppearCallHeroSelect(manager.actNum, index); CloseWindow(); }); previewButton.SetListener(() => { HeroUIManager.Instance.selectForPreviewHeroID = manager.nowCallChooseHeroID; UIManager.Instance.OpenWindow<HeroBestBaseWin>(); }); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; manager.OnNowCallChooseHeroIDChangeEvent += OnNowCallChooseHeroIDChangeEvent; manager.nowCallChooseHeroID = manager.GetCurrentDisplayCallHeroId(); Display(); CreateScroller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnNowCallChooseHeroIDChangeEvent -= OnNowCallChooseHeroIDChangeEvent; } private void OnNowCallChooseHeroIDChangeEvent() { Display(); scroller.m_Scorller.RefreshActiveCellViews(); } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnCallChangeCell; _cell.Display(cell.index); } void CreateScroller() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; var arr = config.ActHeroIDList; if (arr.IsNullOrEmpty()) return; scroller.Refresh(); int rowCount = (int)Mathf.Ceil((float)arr.Length / rowCountMax); for (int i = 0; i < rowCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } scroller.Restart(); } void Display() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; int skinID = manager.GetDefaultSkinID(manager.nowCallChooseHeroID); var skinConfig = HeroSkinConfig.Get(skinID); if (skinConfig == null) return; uiHeroController.Create(skinID, 1); } } Main/System/HeroReturn/HeroReturnCallChangeWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 8aa8fd53cfed7704f8a1b6b0b8d75407 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallChooseCell.cs
New file @@ -0,0 +1,33 @@ using UnityEngine; public class HeroReturnCallChooseCell : CellView { [SerializeField] HeroReturnCallChooseItem[] items; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int rowIndex) { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; var heroArr = config.ActHeroIDList; if (heroArr.IsNullOrEmpty()) return; for (int i = 0; i < items.Length; i++) { int index = rowIndex * HeroReturnCallChangeWin.rowCountMax + i; if (index < heroArr.Length) { items[i].SetActive(true); items[i].Display(index, heroArr, act.CfgID); } else { items[i].SetActive(false); } } } } Main/System/HeroReturn/HeroReturnCallChooseCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 0f45542ad2c6a5a4a9b16dacda70e468 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallChooseItem.cs
New file @@ -0,0 +1,41 @@ using UnityEngine; using UnityEngine.UI; public class HeroReturnCallChooseItem : MonoBehaviour { [SerializeField] HeroHeadBaseCell heroHeadBaseCell; [SerializeField] Image jobImg; [SerializeField] Text nameText; [SerializeField] Transform select; HeroReturnManager manager => HeroReturnManager.Instance; HeroConfig heroConfig; int index; public void Display(int index, int[] heroIds, int cfgId) { this.index = index; if (heroIds?.Length <= index) return; int heroId = heroIds[index]; heroConfig = HeroConfig.Get(heroId); if (heroConfig == null) return; int skinID = manager.GetDefaultSkinID(heroId); var heroSkinConfig = HeroSkinConfig.Get(skinID); if (heroSkinConfig == null) return; heroHeadBaseCell.Init(heroConfig.HeroID, skinID, 0, 0, 0, OnClick); nameText.text = heroConfig.Name; jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class)); bool isChoose = manager.nowCallChooseHeroID == heroId; select?.SetActive(isChoose); } public void OnClick() { if (heroConfig == null) return; manager.nowCallChooseHeroID = heroConfig.HeroID; } } Main/System/HeroReturn/HeroReturnCallChooseItem.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 05796103e33a5c44b9ab102ee2fde400 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallChooseWin.cs
New file @@ -0,0 +1,95 @@ using UnityEngine; public class HeroReturnCallChooseWin : UIBase { [SerializeField] ScrollerController scroller; [SerializeField] ButtonEx closeButton; [SerializeField] ButtonEx okButton; [SerializeField] ButtonEx previewButton; [SerializeField] UIHeroController uiHeroController; public const int rowCountMax = 4; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); okButton.SetListener(() => { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; int index = manager.GetHeroIdIndex(act.CfgID, manager.nowCallChooseHeroID); if (index < 0) return; manager.SnedHeroAppearCallHeroSelect(manager.actNum, index); manager.SaveCallChooseHeroStateKey(act); CloseWindow(); }); previewButton.SetListener(() => { HeroUIManager.Instance.selectForPreviewHeroID = manager.nowCallChooseHeroID; UIManager.Instance.OpenWindow<HeroBestBaseWin>(); }); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; manager.OnNowCallChooseHeroIDChangeEvent += OnNowCallChooseHeroIDChangeEvent; manager.nowCallChooseHeroID = manager.GetCurrentDisplayCallHeroId(); Display(); CreateScroller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnNowCallChooseHeroIDChangeEvent -= OnNowCallChooseHeroIDChangeEvent; } private void OnNowCallChooseHeroIDChangeEvent() { Display(); scroller.m_Scorller.RefreshActiveCellViews(); } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnCallChooseCell; _cell.Display(cell.index); } void CreateScroller() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; var arr = config.ActHeroIDList; if (arr.IsNullOrEmpty()) return; scroller.Refresh(); int rowCount = (int)Mathf.Ceil((float)arr.Length / rowCountMax); for (int i = 0; i < rowCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } scroller.Restart(); } void Display() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; int skinID = manager.GetDefaultSkinID(manager.nowCallChooseHeroID); var skinConfig = HeroSkinConfig.Get(skinID); if (skinConfig == null) return; uiHeroController.Create(skinID, 1); } } Main/System/HeroReturn/HeroReturnCallChooseWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: df583e8bc2fc9ab47ab8db4a977622bc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallHistoryCell.cs
New file @@ -0,0 +1,42 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnCallHistoryCell : CellView { [SerializeField] Color nameColor; [SerializeField] TextEx infoText; public virtual void Display(int index, List<HeroReturnGameRec> list) { if (list?.Count <= index) return; var rec = list[index]; var itemconfig = ItemConfig.Get(rec.ItemID); if (itemconfig == null) return; //150 整个武将 if (itemconfig.Type == 150) { HeroConfig heroConfig = HeroConfig.Get(rec.ItemID); if (heroConfig == null) return; int quality = heroConfig.Quality; infoText.text = Language.Get("HeroDebut29", UIHelper.AppendColor(nameColor, rec.PlayerName), UIHelper.AppendColor(UIHelper.GetUIColorByFunc(quality), Language.Get(StringUtility.Concat("CommonQuality", quality.ToString()))), UIHelper.AppendColor(UIHelper.GetUIColorByFunc(quality), heroConfig.Name.ToString()) ); } else { int quality = itemconfig.ItemColor; infoText.text = Language.Get("HeroDebut30", UIHelper.AppendColor(nameColor, rec.PlayerName), UIHelper.AppendColor(UIHelper.GetUIColorByFunc(quality), itemconfig.ItemName.ToString()), rec.ItemCount.ToString() ); } } } Main/System/HeroReturn/HeroReturnCallHistoryCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 38c9c575a3a11064597472dbd5e95a43 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallHistoryOutCell.cs
New file @@ -0,0 +1,21 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnCallHistoryOutCell : HeroReturnCallHistoryCell { [SerializeField] CanvasGroup canvasGroup; public override void Display(int index, List<HeroReturnGameRec> list) { base.Display(index, list); } // 提供给外部设置透明度的方法 public void SetAlpha(float alpha) { if (canvasGroup != null) { canvasGroup.alpha = alpha; } } } Main/System/HeroReturn/HeroReturnCallHistoryOutCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 8239f369fcc315847a4e250422c234d6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallHistoryWin.cs
New file @@ -0,0 +1,57 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnCallHistoryWin : UIBase { [SerializeField] ScrollerController scroller; [SerializeField] RectTransform noRect; HeroReturnManager manager => HeroReturnManager.Instance; protected override void OnPreOpen() { scroller.lockType = EnhanceLockType.LockVerticalBottom; scroller.OnRefreshCell += OnRefreshCell; manager.OnUpdateGameRecInfo += OnUpdateGameRecInfo; CreateScroller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnUpdateGameRecInfo -= OnUpdateGameRecInfo; } private void OnUpdateGameRecInfo() { scroller.m_Scorller.RefreshActiveCellViews(); } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnCallHistoryCell; _cell.Display(cell.index, list); } public List<HeroReturnGameRec> list; void CreateScroller() { list = manager.GetGameRecList(); if (list == null) { noRect.SetActive(true); scroller.SetActive(false); return; } noRect.SetActive(false); scroller.SetActive(true); scroller.Refresh(); for (int i = 0; i < list.Count; i++) { scroller.AddCell(ScrollerDataType.Header, i); } scroller.Restart(); } } Main/System/HeroReturn/HeroReturnCallHistoryWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 10151abcb0caf394aa8caa2c00f25bbe MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallRateCell.cs
New file @@ -0,0 +1,28 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnCallRateCell : CellView { [SerializeField] HeroReturnCallRateItem[] items; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int rowIndex, Dictionary<int, int> gridRateDict, List<int> gridList, XBGetItemConfig xbConfig) { if (gridList == null) return; for (int i = 0; i < items.Length; i++) { int index = rowIndex * HeroReturnCallChangeWin.rowCountMax + i; if (index < gridList.Count) { items[i].SetActive(true); items[i].Display(index, gridRateDict, gridList, xbConfig); } else { items[i].SetActive(false); } } } } Main/System/HeroReturn/HeroReturnCallRateCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: cc363b85a77d3ce4b92b8f4ce95f524f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallRateHeroCell.cs
New file @@ -0,0 +1,28 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnCallRateHeroCell : CellView { [SerializeField] ItemCell[] itemCells; public void Display(int rowIndex, List<Item> dataList) { if (dataList == null) return; for (int i = 0; i < itemCells.Length; i++) { int dataIndex = rowIndex * HeroReturnCallRateHeroWin.rowCountMax + i; if (dataIndex < dataList.Count) { itemCells[i].SetActive(true); itemCells[i].Init(new ItemCellModel(dataList[dataIndex].id, true, dataList[dataIndex].countEx)); itemCells[i].button.SetListener(() => ItemTipUtility.Show(dataList[dataIndex].id)); } else { itemCells[i].SetActive(false); } } } } Main/System/HeroReturn/HeroReturnCallRateHeroCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 75a05dc1b9031fa40b0fea8347aceca7 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallRateHeroWin.cs
New file @@ -0,0 +1,119 @@ using System.Collections.Generic; using Cysharp.Threading.Tasks; using UnityEngine; public class HeroReturnCallRateHeroWin : UIBase { [SerializeField] RectTransform rectTransform; [SerializeField] RectTransform arrowImage; [SerializeField] RectTransform arrowUpImage; [SerializeField] ScrollerController scroller; public static Vector3 worldPos; //世界坐标系位置 public static bool isDownShow = false; // 是否向下显示 public static List<Item> dataList; public const int rowCountMax = 4; protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; rectTransform.position = new Vector3(100, 100, 100); //初始化时,屏幕范围外 arrowImage.SetActive(!isDownShow); arrowUpImage.SetActive(isDownShow); CreateScroller(); } protected override void OnPreClose() { isDownShow = false; scroller.OnRefreshCell -= OnRefreshCell; } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnCallRateHeroCell; _cell.Display(cell.index, dataList); } void CreateScroller() { if (dataList == null || dataList.Count == 0) return; scroller.Refresh(); int rowCount = Mathf.CeilToInt((float)dataList.Count / rowCountMax); for (int i = 0; i < rowCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } scroller.Restart(); } protected override void OnOpen() { UpdatePos().Forget(); } async UniTask UpdatePos() { await UniTask.DelayFrame(3); // 限制在屏幕范围内 Vector3[] corners = new Vector3[4]; rectTransform.GetWorldCorners(corners); float minY = corners[0].y; float maxY = corners[0].y; for (int i = 1; i < corners.Length; i++) { if (corners[i].y < minY) minY = corners[i].y; if (corners[i].y > maxY) maxY = corners[i].y; } float screenHeight = maxY - minY; Vector2 adjustedPos = new Vector2(worldPos.x, worldPos.y + (!isDownShow ? screenHeight * 0.5f : -screenHeight * 0.5f)); Vector2 screenAdjustedPos = CameraManager.uiCamera.WorldToScreenPoint(adjustedPos); var rectWidth = rectTransform.rect.width * Screen.width / canvasScaler.referenceResolution.x; screenAdjustedPos.x = Mathf.Clamp(screenAdjustedPos.x, rectWidth * 0.5f, Screen.width - rectWidth * 0.5f); screenAdjustedPos.y = Mathf.Clamp(screenAdjustedPos.y, rectTransform.rect.height * 0.5f, Screen.height - rectTransform.rect.height * 0.5f - 15); adjustedPos = CameraManager.uiCamera.ScreenToWorldPoint(screenAdjustedPos); rectTransform.position = adjustedPos; if (!isDownShow) { rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y + 15, rectTransform.localPosition.z); } else { rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y - 15, rectTransform.localPosition.z); } rectTransform.GetWorldCorners(corners); float minX = corners[0].x; float maxX = corners[0].x; for (int i = 1; i < corners.Length; i++) { if (corners[i].x < minX) minX = corners[i].x; if (corners[i].x > maxX) maxX = corners[i].x; } //显示arrowImage 的x轴上的位置,和worldPos同步,但不超过minX 和 maxX范围 if (!isDownShow) { Vector3 arrowImagePosition = arrowImage.position; arrowImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX); arrowImage.position = arrowImagePosition; } else { Vector3 arrowUpImagePosition = arrowUpImage.position; arrowUpImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX); arrowUpImage.position = arrowUpImagePosition; } } } Main/System/HeroReturn/HeroReturnCallRateHeroWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 4488cbc55bbabcf43b390ebb827ec1f8 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallRateItem.cs
New file @@ -0,0 +1,123 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HeroReturnCallRateItem : MonoBehaviour { [SerializeField] ButtonEx libButton; [SerializeField] ItemCell itemCell; [SerializeField] Text rateText; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int index, Dictionary<int, int> gridRateDict, List<int> gridList, XBGetItemConfig xbConfig) { if (gridList?.Count <= index || gridRateDict?.Count != gridList?.Count || xbConfig == null) return; if (xbConfig?.GridItemInfo == null || xbConfig?.GridLibInfo == null) return; if (manager.xbGridArr == null) return; int grid = gridList[index]; int rate = gridRateDict[grid]; rateText.text = Language.Get("TimingGift02", (double)rate / (double)100.0); SetItemCell(grid, xbConfig.GridItemInfo, xbConfig.GridLibInfo, manager.xbGridArr); } public void SetCountActive(ItemCell itemCell, long count) { itemCell.countText.SetActive(count > 1); } private void SetItemCell(int grid, Dictionary<int, int[]> gridItemInfo, Dictionary<int, int> gridLibInfo, int[] xbGridArr) { libButton.SetActive(false); itemCell.SetActive(false); if (gridItemInfo.TryGetValue(grid, out var itemInfo)) { itemCell.SetActive(true); itemCell.Init(new ItemCellModel(itemInfo[0], true, itemInfo[1])); SetCountActive(itemCell, itemInfo[1]); itemCell.button.SetListener(() => ItemTipUtility.Show(itemInfo[0])); return; } if (!gridLibInfo.TryGetValue(grid, out var libID)) return; var list = TreasureItemLibConfig.GetItemIDList(libID); if (list == null) return; if (xbGridArr == null) return; if (xbGridArr.Contains(grid)) { int heroID = manager.GetCurrentDisplayCallHeroId(); if (!TryGetHeroItemInfo(heroID, libID, list, out int itemID, out int itemCount)) return; itemCell.SetActive(true); itemCell.Init(new ItemCellModel(itemID, true, itemCount)); SetCountActive(itemCell, itemCount); itemCell.button.SetListener(() => ItemTipUtility.Show(itemID)); } else { libButton.SetActive(true); libButton.SetListener(() => { HeroReturnCallRateHeroWin.worldPos = libButton.transform.position; HeroReturnCallRateHeroWin.dataList = GetLibItemList(libID, list); HeroReturnCallRateHeroWin.isDownShow = true; UIManager.Instance.OpenWindow<HeroReturnCallRateHeroWin>(); }); } } public List<Item> GetLibItemList(int libID, List<int> itemList) { List<Item> res = new(); for (int i = 0; i < itemList.Count; i++) { int itemID = itemList[i]; var config = ItemConfig.Get(itemID); if (config == null) continue; if (!TreasureItemLibConfig.TryGetID(libID, itemID, out int id)) continue; var treasureItemLibConfig = TreasureItemLibConfig.Get(id); if (treasureItemLibConfig == null) continue; res.Add(new Item(itemID, treasureItemLibConfig.ItemCount)); } return res; } public bool TryGetHeroItemInfo(int heroID, int libID, List<int> itemList, out int itemID, out int itemCount) { itemID = 0; itemCount = 0; if (itemList == null) return false; for (int i = 0; i < itemList.Count; i++) { itemID = itemList[i]; var config = ItemConfig.Get(itemID); if (config == null) continue; if (!TreasureItemLibConfig.TryGetID(libID, itemID, out int id)) continue; var treasureItemLibConfig = TreasureItemLibConfig.Get(id); if (treasureItemLibConfig == null) continue; //本体 if (config.Type == 150) { if (heroID == itemID) { itemCount = treasureItemLibConfig.ItemCount; return true; } } else if (config.Type == 151) { if (heroID == config.EffectValueA1) { itemCount = treasureItemLibConfig.ItemCount; return true; } } } return false; } } Main/System/HeroReturn/HeroReturnCallRateItem.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e8caa7644bce7414d9ada3cef9ee1eff MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallRateWin.cs
New file @@ -0,0 +1,83 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnCallRateWin : UIBase { [SerializeField] ScrollerController scroller; public const int rowCountMax = 4; HeroReturnManager manager => HeroReturnManager.Instance; protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; CreateScroller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnCallRateCell; _cell.Display(cell.index, gridRateDict, gridList, xbConfig); } Dictionary<int, int> gridRateDict; List<int> gridList; XBGetItemConfig xbConfig; void CreateScroller() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; xbConfig = HappyXBModel.Instance.GetXBItemConfigByType(config.ActTreasureType); if (xbConfig == null || xbConfig.GridItemRateList1 == null) return; gridRateDict = GetGridRateDict(xbConfig.GridItemRateList1); if (gridRateDict == null) return; gridList = GetSortedGridList(); if (gridList == null) return; scroller.Refresh(); int rowCount = (int)Mathf.Ceil((float)gridList.Count / rowCountMax); for (int i = 0; i < rowCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } scroller.Restart(); } //<格子,万分率> public Dictionary<int, int> GetGridRateDict(int[][] gridItemRateList1) { Dictionary<int, int> res = new(); for (int i = 0; i < gridItemRateList1.Length; i++) { res[gridItemRateList1[i][1]] = i == 0 ? gridItemRateList1[i][0] : gridItemRateList1[i][0] - gridItemRateList1[i - 1][0]; } return res; } public List<int> GetSortedGridList() { if (gridRateDict == null || gridRateDict.Count == 0) return null; List<int> sortedGrids = new List<int>(gridRateDict.Keys); sortedGrids.Sort(); // sortedGrids.Sort((a, b) => // { // int rateA = gridRateDict[a]; // int rateB = gridRateDict[b]; // return rateA.CompareTo(rateB); // }); return sortedGrids; } } Main/System/HeroReturn/HeroReturnCallRateWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 3dc8fff9b1f118d4682a6541f30741a0 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallResultCell.cs
New file @@ -0,0 +1,104 @@ using UnityEngine; using DG.Tweening; public class HeroReturnCallResultCell : MonoBehaviour { [SerializeField] public ItemCell itemCell; [SerializeField] UIEffectPlayer orbBaseEffect; // 初始状态特效 [SerializeField] UIEffectPlayer orbBoomEffect; // 爆发瞬间特效 [SerializeField] UIEffectPlayer orbQualityEffect; // 品质底色特效 [SerializeField] UIEffectPlayer flowEffect; // 最终流光特效 [HideInInspector] public Vector3 originalLocalPos; void Awake() { // 记录初始本地坐标,用于发牌动画的归位 originalLocalPos = transform.localPosition; } /// <summary> /// 初始化格子数据 /// </summary> public void DisplayItemCell(int itemID, int count) { itemCell.Init(new ItemCellModel(itemID, true, count)); itemCell.button.SetListener(() => ItemTipUtility.Show(itemID)); } /// <summary> /// 重置所有 UI 元素和特效至初始状态 /// </summary> public void ResetState() { itemCell.gameObject.SetActive(false); orbBaseEffect.SetActive(false); orbBoomEffect.SetActive(false); orbQualityEffect.SetActive(false); flowEffect.SetActive(false); } /// <summary> /// 阶段 1:播放初始引导光点(飞行阶段) /// </summary> public void PlayInitialOrb() { orbBaseEffect.SetActive(true); orbBoomEffect.SetActive(false); orbQualityEffect.SetActive(false); orbBaseEffect.Play(4); // 播放索引为4的通用飞行效 } /// <summary> /// 阶段 2 & 3:执行爆开、显色、翻牌、展示流光的组合序列 /// </summary> /// <param name="qualityIndex">品质底色特效索引</param> /// <param name="flowQualityIndex">最终流光特效索引</param> /// <returns>返回 Sequence 方便外部进行 Stagger(交错)排列</returns> public Tween PlayExplosionFadeAndFlipReveal(int qualityIndex, int flowQualityIndex) { Sequence seq = DOTween.Sequence(); // [0.0s] 切换特效:关闭飞行态,触发爆发态 seq.InsertCallback(0f, () => { orbBaseEffect.SetActive(false); orbBoomEffect.SetActive(true); orbBoomEffect.Play(3); }); // [0.2s] 展示品质基色 seq.InsertCallback(0.2f, () => { orbQualityEffect.transform.localScale = Vector3.zero; orbQualityEffect.SetActive(true); orbQualityEffect.Play(qualityIndex); }); // 品质光团由小变大的回弹动画 seq.Insert(0.2f, orbQualityEffect.transform.DOScale(Vector3.one, 0.2f).SetEase(Ease.OutBack)); // [0.8s] 准备翻牌:激活 ItemCell 并设置 90 度侧向,准备旋转 seq.InsertCallback(0.8f, () => { itemCell.gameObject.SetActive(true); itemCell.transform.localEulerAngles = new Vector3(0, 90f, 0); }); // [0.8s] 翻转动作(耗时 0.3s):从 90 度旋转回 0 度 seq.Insert(0.8f, itemCell.transform.DOLocalRotate(Vector3.zero, 0.3f, RotateMode.Fast).SetEase(Ease.OutSine)); // [1.1s] 序列完结:清理临时特效,激活持久流光 seq.InsertCallback(1.1f, () => { orbBoomEffect.SetActive(false); orbQualityEffect.SetActive(false); flowEffect.SetActive(true); flowEffect.Play(flowQualityIndex); }); return seq; } } Main/System/HeroReturn/HeroReturnCallResultCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: aa9f5a1a80f17304b84d946832fe6381 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallResultWin.cs
New file @@ -0,0 +1,370 @@ using UnityEngine; using DG.Tweening; using System.Collections.Generic; public class HeroReturnCallResultWin : UIBase { [SerializeField] Transform moneyRect; [SerializeField] OwnItemCell ownItemCell; [SerializeField] ItemCell presentItemCell; // 抽卡获得的赠送道具 [SerializeField] RectTransform oneRect; // 单抽容器中心点 [SerializeField] HeroReturnCallResultCell oneCell; // 单抽单元格 [SerializeField] RectTransform tenRect; // 十连容器 [SerializeField] HeroReturnCallResultCell[] tenCell; // 十连单元格数组 [SerializeField] UIEffectPlayer firstEffect; // 开屏初始特效 [SerializeField] HeroReturnCallButton callButton; // 再次抽取按钮 [SerializeField] ButtonEx okButton; // 确定返回按钮 HeroReturnManager manager => HeroReturnManager.Instance; HappyXBModel xbManager => HappyXBModel.Instance; bool isSkip; // 是否跳过动画 int treasureType; // 抽卡宝库类型 bool isOne = false; // 是否为单抽模式 private Sequence animSeq; // 主动画序列 protected override void InitComponent() { okButton.SetListener(CloseWindow); } protected override void OnPreOpen() { animSeq?.Kill(); var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; treasureType = config.ActTreasureType; // 根据配置和时间戳加载用户的是否跳过动画设置 isSkip = manager.LoadCallSkipData(config.CfgID, act.startDate, act.endDate); // 绑定数据刷新回调 HappyXBModel.Instance.RefreshXBResultAct += RefreshXBResultAct; HappyXBModel.Instance.RefreshXBTypeInfoAct += OnRefreshXBTypeInfoAct; var treasureSetConfig = TreasureSetConfig.Get(config.ActTreasureType); if (treasureSetConfig == null) return; ownItemCell.itemID = treasureSetConfig.CostItemID; RefreshXBResultAct(); } protected override void OnPreClose() { animSeq?.Kill(); // 解绑回调,防止内存泄漏 HappyXBModel.Instance.RefreshXBResultAct -= RefreshXBResultAct; HappyXBModel.Instance.RefreshXBTypeInfoAct -= OnRefreshXBTypeInfoAct; } /// <summary> /// 刷新抽卡结果界面 /// </summary> void RefreshXBResultAct() { isOne = HeroUIManager.Instance.selectCallIndex == 0; // 初始化顶部赠送物品 int itemId = xbManager.addXBAddItemID; long count = xbManager.addXBItemCount; presentItemCell.Init(new ItemCellModel(itemId, true, count)); presentItemCell.button.SetListener(() => ItemTipUtility.Show(itemId)); // 根据单抽或十连填充物品数据 if (isOne) { if (!xbManager.xbResultDict.IsNullOrEmpty()) { oneCell.DisplayItemCell(xbManager.xbResultDict[0].itemId, xbManager.xbResultDict[0].count); } } else { for (int i = 0; i < tenCell.Length; i++) { if (i < xbManager.xbResultDict?.Count) { tenCell[i].DisplayItemCell(xbManager.xbResultDict[i].itemId, xbManager.xbResultDict[i].count); } } } callButton.Display(treasureType, HeroUIManager.Instance.selectCallIndex); if (isSkip) { // 模式:跳过动画,直接显示最终状态 firstEffect.SetActive(false); ShowImmediate(); } else { // 模式:播放完整展示动画 PrepareAnimation(); firstEffect.SetActive(true); firstEffect.Play(0); // 预留 1.1s 的开屏动效时间后,开始播放发牌/翻牌序列 PlayResultAnimation(1.1f); } } private void OnRefreshXBTypeInfoAct() { RefreshXBResultAct(); } /// <summary> /// 静态显示(无动画直接展示结果) /// </summary> private void ShowImmediate() { animSeq?.Kill(); oneRect.SetActive(isOne); tenRect.SetActive(!isOne); ownItemCell.SetActive(true); moneyRect.SetActive(true); presentItemCell.SetActive(true); callButton.SetActive(true); okButton.SetActive(true); if (isOne) { oneCell.SetActive(true); oneCell.ResetState(); oneCell.itemCell.SetActive(true); } else { for (int i = 0; i < tenCell.Length; i++) { if (i < xbManager.xbResultDict?.Count) { tenCell[i].SetActive(true); tenCell[i].transform.localPosition = tenCell[i].originalLocalPos; tenCell[i].ResetState(); tenCell[i].itemCell.SetActive(true); } else { tenCell[i].SetActive(false); } } } } /// <summary> /// 动画前置准备(隐藏元素并重置坐标) /// </summary> private void PrepareAnimation() { oneRect.SetActive(isOne); tenRect.SetActive(!isOne); ownItemCell.SetActive(false); moneyRect.SetActive(false); presentItemCell.SetActive(false); callButton.SetActive(false); okButton.SetActive(false); if (isOne) { oneCell.SetActive(true); oneCell.ResetState(); } else { for (int i = 0; i < tenCell.Length; i++) { if (i < xbManager.xbResultDict?.Count) { tenCell[i].SetActive(true); tenCell[i].ResetState(); tenCell[i].transform.localPosition = tenCell[i].originalLocalPos; } else { tenCell[i].SetActive(false); } } } } /// <summary> /// 核心逻辑:编排结果展示动画时间轴 /// </summary> private void PlayResultAnimation(float startDelay = 0f) { animSeq?.Kill(); animSeq = DOTween.Sequence(); if (isOne) { // ==================== 单抽动画逻辑 ==================== float timelineCursor = startDelay; // 1. 播放中心光团 animSeq.InsertCallback(timelineCursor, () => oneCell.PlayInitialOrb()); // 预留短暂的展示时间 float finishShowTime = 0.12f; timelineCursor += finishShowTime; // 2. 触发爆开与翻牌组合动画 int itemId = xbManager.xbResultDict[0].itemId; int quality = GetOrbQuality(itemId); int flowQuality = GetFlowQuality(itemId); animSeq.Insert(timelineCursor, oneCell.PlayExplosionFadeAndFlipReveal(quality, flowQuality)); // 推进游标至组合动画结束(1.1s基础时长 + 0.3s缓冲) timelineCursor += 1.4f; // 3. 弹出底部 UI animSeq.InsertCallback(timelineCursor, ShowBottomUI); } else { // ==================== 十连动画逻辑 ==================== int count = xbManager.xbResultDict.Count; float staggerInterval = 0.1f; // 发牌间隔 float moveDuration = 0.12f; // 飞行时间 float timelineCursor = startDelay; // 1. 依次从中心点向目标位置发射光团(发牌阶段) for (int i = 0; i < count; i++) { var cell = tenCell[i]; cell.transform.position = oneRect.position; // 起始于中心 float delay = timelineCursor + i * staggerInterval; animSeq.InsertCallback(delay, () => cell.PlayInitialOrb()); animSeq.Insert(delay, cell.transform.DOLocalMove(cell.originalLocalPos, moveDuration).SetEase(Ease.OutCubic)); } // 计算所有卡牌完成飞行的时刻 float finishFlyingTime = ((count - 1) * staggerInterval) + moveDuration; timelineCursor += finishFlyingTime; // 2. 依次触发爆开翻牌动画(展示阶段) for (int i = 0; i < count; i++) { int itemId = xbManager.xbResultDict[i].itemId; int quality = GetOrbQuality(itemId); int flowQuality = GetFlowQuality(itemId); animSeq.Insert(timelineCursor + i * staggerInterval, tenCell[i].PlayExplosionFadeAndFlipReveal(quality, flowQuality)); } // 计算全部卡牌翻转完成的时间点并加入缓冲 float finalFlipDuration = 1.1f + ((count - 1) * staggerInterval) + 0.3f; timelineCursor += finalFlipDuration; // 3. 弹出底部 UI animSeq.InsertCallback(timelineCursor, ShowBottomUI); } } /// <summary> /// 展示底部操作按钮,并检查是否触发武将立绘 /// </summary> private void ShowBottomUI() { ownItemCell.SetActive(true); moneyRect.SetActive(true); presentItemCell.SetActive(true); callButton.SetActive(true); okButton.SetActive(true); presentItemCell.transform.localScale = Vector3.zero; callButton.transform.localScale = Vector3.zero; okButton.transform.localScale = Vector3.zero; Sequence bottomSeq = DOTween.Sequence(); bottomSeq.Append(presentItemCell.transform.DOScale(Vector3.one, 0.3f).SetEase(Ease.OutBack)); bottomSeq.Join(callButton.transform.DOScale(Vector3.one, 0.3f).SetEase(Ease.OutBack)); bottomSeq.Join(okButton.transform.DOScale(Vector3.one, 0.3f).SetEase(Ease.OutBack)); bottomSeq.OnComplete(() => { if (!isSkip) { CheckAndShowHeroLH(); } }); animSeq.Append(bottomSeq); } /// <summary> /// 检测并展示高品质武将立绘(弹窗展示) /// </summary> private void CheckAndShowHeroLH() { // 清理缓存列表 ItemLogicUtility.Instance.poplhHeroIdList.Clear(); List<int> uniqueHeroIds = new List<int>(); int count = xbManager.xbResultDict.Count; for (int i = 0; i < count; i++) { int itemId = xbManager.xbResultDict[i].itemId; // 仅对 HeroConfig 中存在的完整武将进行处理 if (HeroConfig.HasKey(itemId)) { // 仅展示高于设定品质的武将 if (HeroConfig.Get(itemId).Quality < HappyXBModel.Instance.lhQuality) continue; if (!uniqueHeroIds.Contains(itemId)) { uniqueHeroIds.Add(itemId); } } } // 如果存在符合条件的武将,打开大图展示界面 if (uniqueHeroIds.Count > 0) { ItemLogicUtility.Instance.poplhHeroIdList = uniqueHeroIds; if (!UIManager.Instance.IsOpenedInList<HeroShowLHWin>()) { UIManager.Instance.OpenWindow<HeroShowLHWin>(); } } } // --- 辅助方法:映射配置品质到特效索引 --- private int GetOrbQuality(int itemId) { int qualityLevel = ItemConfig.Get(itemId).ItemColor; switch (qualityLevel) { case 2: return 5; // 紫色 case 3: return 2; // 黄色 case 4: return 0; // 橙色 case 5: return 1; // 红色 default: return 0; } } private int GetFlowQuality(int itemId) { int qualityLevel = ItemConfig.Get(itemId).ItemColor; switch (qualityLevel) { case 2: return 3; // 紫色 case 3: return 2; // 黄色 case 4: return 0; // 橙色 case 5: return 1; // 红色 default: return 0; } } } Main/System/HeroReturn/HeroReturnCallResultWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: fafde75987e7b864ea3c2faa42578100 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCallWin.cs
New file @@ -0,0 +1,417 @@ 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<HeroReturnShopWin>()); giftButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnGiftWin>()); changeHeroButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnCallChangeWin>()); rankButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnRankWin>()); rateButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnCallRateWin>()); historyButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnCallHistoryWin>()); chooseHeroButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnCallChooseWin>()); 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<CanvasGroup>(); if (cg == null) cg = lhController.gameObject.AddComponent<CanvasGroup>(); 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<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 = 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(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 = 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<HeroReturnGameRec> 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; 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); } } Main/System/HeroReturn/HeroReturnCallWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 0774834d6226ea848adedc229e82552f MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCell.cs
New file @@ -0,0 +1,30 @@ using UnityEngine; public class HeroReturnCell : MonoBehaviour { [SerializeField] ButtonEx clickButton; [SerializeField] ImageEx bgImage; [SerializeField] ImageEx heroImage; [SerializeField] GradientText titleText; HeroReturnManager manager => HeroReturnManager.Instance; public void Display() { clickButton.SetListener(() => { UIManager.Instance.OpenWindow<HeroReturnWin>(); }); int heroID = manager.GetFirstHeroId(); var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; int skinID = manager.GetDefaultSkinID(heroID); var skinConfig = HeroSkinConfig.Get(skinID); if (skinConfig == null) return; bgImage.SetSprite(artConfig.EntryBgImage); manager.SetHeroSquareIcon(heroImage, skinConfig.SquareIcon); titleText.text = artConfig.EntryTitleText; } } Main/System/HeroReturn/HeroReturnCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: dc2b313f9675a0644bd1a684fe9bad47 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCheckInCell.cs
New file @@ -0,0 +1,60 @@ using UnityEngine; public class HeroReturnCheckInCell : MonoBehaviour { [SerializeField] ButtonEx clickButton; [SerializeField] ImageEx bgImage; [SerializeField] TextEx dayText; [SerializeField] TextEx itemNameText; [SerializeField] ItemCell itemCell; [SerializeField] UIEffectPlayer uiEffectPlayer; [SerializeField] Transform imgMask; HeroReturnManager manager => HeroReturnManager.Instance; private int currentItemId; private int currentState; public void Display(int templateID, int dayNum) { uiEffectPlayer.Stop(); var config = ActSignAwardConfig.GetConfig(templateID, dayNum); if (config == null) return; if (config.SignAwardItemList.IsNullOrEmpty()) return; currentItemId = config.SignAwardItemList[0][0]; int count = config.SignAwardItemList[0][1]; var itemConfig = ItemConfig.Get(currentItemId); if (itemConfig == null) return; currentState = manager.GetCheckInState(dayNum); imgMask.SetActive(currentState == 2); bgImage.SetSprite(currentState == 1 ? "HeroDebutCheckInDayBG1" : "HeroDebutCheckInDayBG2"); if (currentState == 1) { uiEffectPlayer.Play(); } dayText.text = Language.Get($"SignDay{dayNum}"); itemNameText.text = itemConfig.ItemName; itemCell.Init(new ItemCellModel(currentItemId, false, count)); itemCell.button.AddListener(OnItemClicked); clickButton.SetListener(() => manager.SendGetCheckInReward()); } private void OnItemClicked() { if (currentState == 1) { manager.SendGetCheckInReward(); } else { ItemTipUtility.Show(currentItemId); } } } Main/System/HeroReturn/HeroReturnCheckInCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 7dc473ad41cdeb049b5ff9072138f709 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnCheckInWin.cs
New file @@ -0,0 +1,81 @@ using UnityEngine; public class HeroReturnCheckInWin : UIBase { [SerializeField] ImageEx bgImage; [SerializeField] UIHeroController rolelhShow; [SerializeField] TextEx timeText; [SerializeField] ButtonEx closeButton; [SerializeField] HeroReturnCheckInCell[] cells; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); } protected override void OnPreOpen() { GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent += OnUpdateActSignInfosEvent; TimeMgr.Instance.OnDayEvent += OnDayEvent; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; Display(); } protected override void OnPreClose() { GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent -= OnUpdateActSignInfosEvent; TimeMgr.Instance.OnDayEvent -= OnDayEvent; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; } private void OnDayEvent() { Display(); } private void OnUpdateActSignInfosEvent(int arg1, int arg2) { Display(); } private void OnSecondEvent() { manager.GetActTimeStr(timeText); } private void Display() { int heroID = manager.GetFirstHeroId(); var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; var heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return; int skinID = manager.GetDefaultSkinID(heroID); var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int templateID = config.SignTempID; var list = ActSignAwardConfig.GetDayNumSortList(templateID); if (list == null) return; bgImage.SetSprite(artConfig.CheckInBgImage); for (int i = 0; i < cells.Length; i++) { if (i < list.Count) { cells[i].SetActive(true); cells[i].Display(templateID, list[i]); } else { cells[i].SetActive(false); } } rolelhShow.Create(skinID, 1, motionName: "", isLh: true); OnSecondEvent(); } } Main/System/HeroReturn/HeroReturnCheckInWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: d4ec9226f50edd6408ce3f2bdb9821ca MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnGiftCell.cs
New file @@ -0,0 +1,165 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnGiftCell : MonoBehaviour { [SerializeField] ImageEx vipImage; [SerializeField] TextEx vipText; [SerializeField] OutlineEx vipTextOutline; [SerializeField] ImageEx rateImage; [SerializeField] TextEx rateText; [SerializeField] ItemCell[] itemCells; [SerializeField] TextEx titleText; [SerializeField] ButtonEx buyButton; [SerializeField] ImageEx buyImage; [SerializeField] TextEx buyText; [SerializeField] TextEx buyText1; [SerializeField] ImageEx moneyIconImage; [SerializeField] TextEx limitCountText; [SerializeField] ImageEx redImage; HeroReturnManager manager => HeroReturnManager.Instance; StoreModel storeModel => StoreModel.Instance; public void Display(int index, List<HeroReturnGiftItem> giftItems) { if (giftItems.IsNullOrEmpty() || index < 0 || index >= giftItems.Count) return; HeroReturnGiftItem item = giftItems[index]; if (item.type == 0) { DisplayStore(item.id); return; } DisplayCTG(item.id); } private void DisplayCTG(int ctgId) { redImage.SetActive(false); buyText.SetActive(true); buyText1.SetActive(false); moneyIconImage.SetActive(false); rateImage.SetActive(true); if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) return; if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) return; if (!CTGConfig.HasKey(ctgId)) return; if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) return; CTGConfig config = CTGConfig.Get(ctgId); vipImage.SetActive(config.VipLevel > 0); if (config.VipLevel > 0) { vipImage.SetSprite($"VipLevel{config.VipLevel}"); vipText.text = Language.Get($"VipLevelInfo{config.VipLevel}"); vipText.color = InvestModel.Instance.GetTextColor(config.VipLevel); vipTextOutline.OutlineColor = InvestModel.Instance.GetOutlineColor(config.VipLevel); } rateImage.SetActive(true); rateText.text = Language.Get("DailySpecials07", config.Percentage); bool isCanBuy = manager.IsCanBuyToday(ctgId); titleText.text = config.Title; buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2"); buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale)); limitCountText.SetActive(config.DailyBuyCount > 0); limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(rechargeCount.todayCount >= config.DailyBuyCount ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, config.DailyBuyCount - rechargeCount.todayCount).ToString())); buyButton.interactable = isCanBuy; buyButton.SetListener(() => { if (config.VipLevel > 0 && !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard)) { SysNotifyMgr.Instance.ShowTip("MinggeAuto8"); return; } if (config.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType)) { SysNotifyMgr.Instance.ShowTip("MinggeAuto5"); UIManager.Instance.OpenWindow<PrivilegeCardWin>(); return; } if (config.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType)) { SysNotifyMgr.Instance.ShowTip("MinggeAuto7"); UIManager.Instance.OpenWindow<PrivilegeCardWin>(); return; } RechargeManager.Instance.CTG(ctgId); }); for (int i = 0; i < itemCells.Length; i++) { var itemBaisc = itemCells[i]; if (i < rechargeItemList.Count) { var itemInfo = rechargeItemList[i]; itemBaisc.SetActive(true); itemBaisc.Init(new ItemCellModel((int)itemInfo.id, false, itemInfo.countEx)); itemBaisc.button.AddListener(() => { ItemTipUtility.Show((int)itemInfo.id); }); } else { itemBaisc.SetActive(false); } } } private void DisplayStore(int id) { rateImage.SetActive(false); vipImage.SetActive(false); if (!StoreConfig.HasKey(id)) return; StoreConfig storeConfig = StoreConfig.Get(id); int remainNum; storeModel.TryGetIsSellOut(storeConfig, out remainNum); bool isFree = manager.IsFreeShop(id); titleText.text = storeConfig.Name; limitCountText.SetActive(!isFree); limitCountText.text = Language.Get("TimeRush08", UIHelper.AppendColor(remainNum == 0 ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, remainNum).ToString(), true)); bool isCanBuy = manager.IsNoSellOutShopID(id); redImage.SetActive(isFree && isCanBuy); buyText.SetActive(isFree || !isCanBuy); buyText.text = isFree ? Language.Get("L1127") : Language.Get("storename11"); buyText1.SetActive(!isFree && isCanBuy); buyText1.text = UIHelper.GetMoneyFormat(storeConfig.MoneyNum); moneyIconImage.SetActive(!isFree && isCanBuy); moneyIconImage.SetIconWithMoneyType(1); buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2"); buyButton.interactable = isCanBuy; buyButton.SetListener(() => { storeModel.SendBuyShopItemWithPopCheck(storeConfig, 1, (int)BuyStoreItemCheckType.ActGift); }); var items = storeModel.GetShopItemlistByIndex(storeConfig); for (int i = 0; i < itemCells.Length; i++) { var itemBaisc = itemCells[i]; if (i < items.Count) { var itemInfo = items[i]; itemBaisc.SetActive(true); itemBaisc.Init(new ItemCellModel(itemInfo.itemId, false, itemInfo.count)); itemBaisc.button.AddListener(() => { ItemTipUtility.Show(itemInfo.itemId); }); } else { itemBaisc.SetActive(false); } } } } Main/System/HeroReturn/HeroReturnGiftCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 4a5a9f2a5a389d24b8e9b1847cf53d35 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnGiftWin.cs
New file @@ -0,0 +1,86 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnGiftWin : UIBase { [SerializeField] ButtonEx closeButton; [SerializeField] ImageEx bgImage; [SerializeField] ImageEx heroImage; [SerializeField] ScrollerController scroller; [SerializeField] TextEx timeText; HeroReturnManager manager => HeroReturnManager.Instance; StoreModel storeModel => StoreModel.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent; int heroID = manager.GetFirstHeroId(); var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; bgImage.SetSprite(artConfig.GiftBgImage); heroImage.SetNativeSize(); heroImage.SetSprite(artConfig.GiftHeroImage); heroImage.SetNativeSize(); OnSecondEvent(); CreateGiftScroller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent; storeModel.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent; } private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroReturnGiftCell>(); _cell?.Display(cell.index, giftItems); } private void OnSecondEvent() { manager.GetActTimeStr(timeText); } private void OnRechargeCountEvent(int obj) { RefreshAll(); } private void RefreshBuyShopLimitEvent() { RefreshAll(); } List<HeroReturnGiftItem> giftItems; private void CreateGiftScroller() { giftItems = manager.GetGiftItemList(true); scroller.Refresh(); if (!giftItems.IsNullOrEmpty()) { for (int i = 0; i < giftItems.Count; i++) { scroller.AddCell(ScrollerDataType.Header, i); } } scroller.Restart(); } void RefreshAll() { scroller.m_Scorller.RefreshActiveCellViews(); } } Main/System/HeroReturn/HeroReturnGiftWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 7cc0cd7de844ca946be560af29b6a17c MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnManager.cs
New file @@ -0,0 +1,1152 @@ using System; using System.Collections.Generic; using System.Linq; using LitJson; using UnityEngine; public class HeroReturnManager : GameSystemManager<HeroReturnManager>, IOpenServerActivity { public int[] xbGridArr; public Dictionary<int, int[][]> heroQaulityColor; public int[][] seeArr; public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent; OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent; OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent; OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent; StoreModel.Instance.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent; GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent += OnUpdateActSignInfosEvent; HeroManager.Instance.onHeroChangeEvent += OnHeroChangeEvent; TimeMgr.Instance.OnDayEvent += OnDayEvent; var config = FuncConfigConfig.Get("HeroAppear"); xbGridArr = JsonMapper.ToObject<int[]>(config.Numerical1); config = FuncConfigConfig.Get("HeroReturn"); heroQaulityColor = ConfigParse.ParseIntArray2Dict(config.Numerical1); seeArr = JsonMapper.ToObject<int[][]>(config.Numerical2); InitRedPointId(); } public void SetheroQaulityColor(GradientText text, int qaulity) { if (!heroQaulityColor.TryGetValue(qaulity, out var colors)) return; if (colors?.Length < 2) return; text.SetVerticalGradient(ParseColor32(colors[0]), ParseColor32(colors[1])); } public override void Release() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk; FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent; OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent; OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent; OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent; StoreModel.Instance.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent; GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent -= OnUpdateActSignInfosEvent; HeroManager.Instance.onHeroChangeEvent -= OnHeroChangeEvent; TimeMgr.Instance.OnDayEvent -= OnDayEvent; } private void OnDayEvent() { UpdateRedpoint(); } private void OnHeroChangeEvent(HeroInfo info) { UpdateRedpoint(); } private void OnUpdateActSignInfosEvent(int arg1, int arg2) { UpdateRedpoint(); } private void RefreshBuyShopLimitEvent() { UpdateRedpoint(); } private void OnBeforePlayerDataInitializeEventOnRelogin() { isSendFirst = true; starHeroIndex = 0; callHeroIndex = 0; starFreeAwardDict.Clear(); } private void OnPlayerLoginOk() { TryPopWin(); } private void OnFuncStateChangeEvent(int obj) { if (obj != (int)FuncOpenEnum.HeroReturn) return; TryPopWin(); } public readonly int sendRankType = 6; public int loadRankType => actNum * 1000 + sendRankType; public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity; public const int activityID = (int)NewDayActivityID.HeroReturnAct; public static OperationType operaType = OperationType.HeroReturn; public Redpoint redPoint = new Redpoint(MainRedDot.HeroReturnRepoint); public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType); public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType); public bool priorityOpen => redPoint.state == RedPointState.Simple; public readonly int actNum = 11; public event Action<int> onStateUpdate; private void OperationTimeUpdateEvent(OperationType type) { if (type == operaType) { if (UIManager.Instance.IsOpened<HeroReturnPopWin>()) UIManager.Instance.CloseWindow<HeroReturnPopWin>(); if (UIManager.Instance.IsOpened<HeroReturnWin>()) UIManager.Instance.CloseWindow<HeroReturnWin>(); UpdateRedpoint(); } } private void OperationStartEvent(OperationType type, int state) { if (type == operaType && state == 0) { onStateUpdate?.Invoke(activityID); TryPopWin(); UpdateRedpoint(); } } private void OperationEndEvent(OperationType type, int state) { if (type == operaType) { onStateUpdate?.Invoke(activityID); if (UIManager.Instance.IsOpened<HeroReturnPopWin>()) UIManager.Instance.CloseWindow<HeroReturnPopWin>(); if (UIManager.Instance.IsOpened<HeroReturnWin>()) UIManager.Instance.CloseWindow<HeroReturnWin>(); UpdateRedpoint(); } } private void OperationAdvanceEvent(OperationType type) { if (type == operaType) { onStateUpdate?.Invoke(activityID); UpdateRedpoint(); } } public OperationHeroAppearInfo GetOperationHeroAppearInfo() { OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationHeroAppearInfo act); return act; } public void SetHeroSquareIcon(ImageEx image, string name) { var sprite = UILoader.LoadSprite("HeroHead", name); if (sprite != null) { image.overrideSprite = sprite; return; } image.SetSprite("herohead_default"); } public void GetActTimeStr(TextEx timeText, string key = "TimeRush05") { var act = GetOperationHeroAppearInfo(); if (act == null) { timeText.text = Language.Get("OSActivity6"); return; } timeText.text = Language.Get(key, TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime())); } public void SetGradientTextColor(GradientText text, int[][] colors) { if (colors?.Length < 4) return; text.topLeftColor = ParseColor32(colors[0]); text.topRightColor = ParseColor32(colors[1]); text.bottomLeftColor = ParseColor32(colors[2]); text.bottomRightColor = ParseColor32(colors[3]); text.SetVerticesDirty(); } public Color32 ParseColor32(int[] colorArr) { return new Color32() { r = (byte)(colorArr.Length > 0 ? colorArr[0] : 0), g = (byte)(colorArr.Length > 1 ? colorArr[1] : 0), b = (byte)(colorArr.Length > 2 ? colorArr[2] : 0), a = (byte)(colorArr.Length > 3 ? colorArr[3] : 255), }; } public int GetDefaultSkinID(int heroID) { HeroConfig heroConfig = HeroConfig.Get(heroID); if (heroConfig == null || heroConfig.SkinIDList.IsNullOrEmpty()) return 0; return heroConfig.SkinIDList[0]; } public bool IsHeroReturnOpen() { if (!IsOpen) return false; if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HeroReturn)) return false; return true; } public int GetHeroIdIndex(int cfgID, int heroID) { var config = ActHeroAppearConfig.Get(cfgID); if (config == null) return 0; var heroArr = config.ActHeroIDList; if (heroArr.IsNullOrEmpty()) return 0; int index = Array.IndexOf(heroArr, heroID); return index; } public event Action OnNowCallChooseHeroIDChangeEvent; private int m_heroAppearActNum = 0; public int nowCallChooseHeroID { get { return m_heroAppearActNum; } set { if (m_heroAppearActNum == value) return; m_heroAppearActNum = value; OnNowCallChooseHeroIDChangeEvent?.Invoke(); } } public event Action OnNowStarUpChooseHeroIDChangeEvent; private int m_nowStarUpChooseHeroID = 0; public int nowStarUpChooseHeroID { get { return m_nowStarUpChooseHeroID; } set { if (m_nowStarUpChooseHeroID == value) return; m_nowStarUpChooseHeroID = value; OnNowStarUpChooseHeroIDChangeEvent?.Invoke(); } } public int starHeroIndex = 0; public int callHeroIndex = 0; //<升星计划选择的武将ID索引,升星计划免费奖励记录> Dictionary<int, uint> starFreeAwardDict = new(); public event Action OnUpdateHeroAppearPlayerInfoEvent; public void UpdateHeroAppearPlayerInfo(HAA22_tagSCActHeroAppearPlayerInfo vNetData) { if (vNetData == null) return; if (vNetData.ActNum != this.actNum) return; int actNum = vNetData.ActNum; starHeroIndex = vNetData.StarHeroIndex; callHeroIndex = vNetData.CallHeroIndex; starFreeAwardDict[starHeroIndex] = vNetData.StarFreeAward; UpdateRedpoint(); OnUpdateHeroAppearPlayerInfoEvent?.Invoke(); } public void SendHeroAppearStarHeroSelect(int actNum, int starHeroIndex) { var pack = new CAA01_tagCSActHeroAppearStarHeroSelect(); pack.ActNum = (byte)actNum; // 活动编号 pack.StarHeroIndex = (byte)starHeroIndex; // 升星计划选择的武将ID索引 GameNetSystem.Instance.SendInfo(pack); } public void SnedHeroAppearCallHeroSelect(int actNum, int callHeroIndex) { var pack = new CAA02_tagCSActHeroAppearCallHeroSelect(); pack.ActNum = (byte)actNum; // 活动编号 pack.CallHeroIndex = (byte)callHeroIndex; // 招募选择的武将ID索引 GameNetSystem.Instance.SendInfo(pack); } public void SendGetStarReward() { var pack = new CA504_tagCMPlayerGetReward(); pack.RewardType = 10; pack.DataEx = (uint)actNum; GameNetSystem.Instance.SendInfo(pack); } #region 红点 public int GetRedPointId(HeroReturnRedPointType type) { return MainRedDot.HeroReturnRepoint * 10 + (int)type; } public Redpoint checkInRedpoint; public Redpoint starUpRedpoint; public Redpoint shopRedpoint; public Redpoint giftRedpoint; public void InitRedPointId() { checkInRedpoint ??= new Redpoint(MainRedDot.HeroReturnRepoint, GetRedPointId(HeroReturnRedPointType.CheckIn)); starUpRedpoint ??= new Redpoint(MainRedDot.HeroReturnRepoint, GetRedPointId(HeroReturnRedPointType.StarUp)); shopRedpoint ??= new Redpoint(MainRedDot.HeroReturnRepoint, GetRedPointId(HeroReturnRedPointType.Shop)); giftRedpoint ??= new Redpoint(MainRedDot.HeroReturnRepoint, GetRedPointId(HeroReturnRedPointType.Gift)); } public void UpdateRedpoint() { redPoint.state = RedPointState.None; checkInRedpoint.state = RedPointState.None; starUpRedpoint.state = RedPointState.None; shopRedpoint.state = RedPointState.None; giftRedpoint.state = RedPointState.None; if (!IsHeroReturnOpen()) return; if (HasCheckInCanHave()) //签到赠礼 { checkInRedpoint.state = RedPointState.Simple; } if (HasStarUpCanHave())//星级提升 { starUpRedpoint.state = RedPointState.Simple; } //兑换商店每天0点显示红点,点击进入一次界面后消失 if (!IsShopVisitedToday) //兑换商店 { shopRedpoint.state = RedPointState.Simple; } if (HasGiftCanHave())//皇权礼包 { giftRedpoint.state = RedPointState.Simple; } } #endregion #region 拍脸界面 public bool IsTodayPop { get { int lastPopTime = LoadPopTimeData(); int todayStartTime = TimeUtility.GetTodayStartTick(); return lastPopTime < todayStartTime; } } private string PopTimeDataKey { get { return $"HeroReturnManager_PopTimeData_{PlayerDatas.Instance.PlayerId}"; } } private int LoadPopTimeData() { return LocalSave.GetInt(PopTimeDataKey); } public void SavePopTimeData() { LocalSave.SetInt(PopTimeDataKey, TimeUtility.AllSeconds); } private void TryPopWin() { if (!IsHeroReturnOpen()) return; if (!IsTodayPop) return; if (UIManager.Instance.IsOpened<HeroReturnPopWin>()) return; if (UIManager.Instance.IsOpened<HeroReturnWin>()) return; PopupWindowsProcessor.Instance.Add("HeroReturnPopWin"); } #endregion #region 签到 private int GetNowDayNum() { var act = GetOperationHeroAppearInfo(); if (act == null) return 0; int dayNum = act.IndexOfDays(TimeUtility.ServerNow); return dayNum < 0 ? 0 : dayNum + 1; } private bool IsCheckInGridUnlock(int gridDayNum) { int nowDayNum = GetNowDayNum(); if (nowDayNum <= 0) return false; return nowDayNum >= gridDayNum; } /// <summary> /// 0-未解锁 1-可签 2-已签 /// </summary> public int GetCheckInState(int gridDayNum) { var act = GetOperationHeroAppearInfo(); if (act == null) return 0; int actType = act.ActType; if (GeneralActInfoManager.Instance.IsDaySigned(actType, actNum, gridDayNum)) return 2; if (IsCheckInGridUnlock(gridDayNum)) return 1; return 0; } public void SendGetCheckInReward() { var act = GetOperationHeroAppearInfo(); if (act == null) return; int actType = act.ActType; GeneralActInfoManager.Instance.SendGetSignReward(actType, actNum); } public bool HasCheckInCanHave() { var act = GetOperationHeroAppearInfo(); if (act == null) return false; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return false; int templateID = config.SignTempID; var list = ActSignAwardConfig.GetDayNumSortList(templateID); if (list == null) return false; for (int i = 0; i < list.Count; i++) { int dayNum = list[i]; int state = GetCheckInState(dayNum); if (state == 1) return true; } return false; } #endregion #region 升星计划 public bool IsSingleHero(OperationHeroAppearInfo act) { var appearConfig = ActHeroAppearConfig.Get(act.CfgID); return appearConfig?.ActHeroIDList?.Length == 1; } public bool IsLockStarHero(OperationHeroAppearInfo act) { // 如果只有一个可选武将,视为锁定 if (IsSingleHero(act)) return true; if (!starFreeAwardDict.TryGetValue(starHeroIndex, out uint freeAward)) return false; //领取了任意一档免费奖励视为锁定 if (freeAward > 0) return true; //购买了任意一档礼包视为锁定 if (IsAnyStarGiftPurchased(act)) return true; return LoadStarUpLockState(act); } /// <summary> /// 检查是否购买了任意一档升星礼包 /// </summary> private bool IsAnyStarGiftPurchased(OperationHeroAppearInfo act) { var appearConfig = ActHeroAppearConfig.Get(act.CfgID); if (appearConfig == null) return false; int starGiftTempID = appearConfig.StarGiftTempID; var list = ActHeroAppearStarConfig.GetHeroReturnAwardIndexSortList(starGiftTempID); if (list.IsNullOrEmpty()) return false; for (int i = 0; i < list.Count; i++) { var config = ActHeroAppearStarConfig.GetConfig(starGiftTempID, list[i]); if (config == null) continue; if (RechargeManager.Instance.TryGetRechargeCount(config.StarGiftCTGID, out var rechargeCount)) { if (rechargeCount.totalCount > 0) { return true; } } } return false; } private string GetStarUpChooseHeroStateKey(OperationHeroAppearInfo act) { if (act == null) return string.Empty; return string.Concat("HeroReturnManager_StarUpChooseHero_", act.CfgID, "_", ToInt(act.startDate), "_", ToInt(act.startDate), "_", PlayerDatas.Instance.PlayerId); } public bool LoadStarUpChooseHeroStateKey(OperationHeroAppearInfo act) { return LocalSave.GetBool(GetStarUpChooseHeroStateKey(act)); } public void SaveStarUpChooseHeroStateKey(OperationHeroAppearInfo act) { LocalSave.SetBool(GetStarUpChooseHeroStateKey(act), true); } private string GetStarUpLockStateKey(OperationHeroAppearInfo act) { if (act == null) return string.Empty; return string.Concat("HeroReturnManager_StarUpLockState_", act.CfgID, "_", ToInt(act.startDate), "_", ToInt(act.startDate), "_", PlayerDatas.Instance.PlayerId); } public bool LoadStarUpLockState(OperationHeroAppearInfo act) { return LocalSave.GetBool(GetStarUpLockStateKey(act)); } public void SaveStarUpLockState(OperationHeroAppearInfo act) { LocalSave.SetBool(GetStarUpLockStateKey(act), true); } /// <summary> /// 当前升星计划选中的武将ID /// </summary> public int GetCurrentDisplayStarUpHeroId() { var act = GetOperationHeroAppearInfo(); if (act == null) return 0; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null || config.ActHeroIDList?.Length <= starHeroIndex) return 0; return config.ActHeroIDList[starHeroIndex]; } private Dictionary<int, Dictionary<int, int[][]>> showHeroGiftItemInfoDict = new(); public bool TryGetStarUpAwardArr(int id, int heroID, out int[][] arr) { arr = null; var config = ActHeroAppearStarConfig.Get(id); if (config == null) return false; var ctgConfig = CTGConfig.Get(config.StarGiftCTGID); if (ctgConfig == null) return false; if (!showHeroGiftItemInfoDict.TryGetValue(id, out var dict)) { dict = new Dictionary<int, int[][]>(); showHeroGiftItemInfoDict[id] = dict; } if (!dict.TryGetValue(heroID, out arr)) { // 如果缓存里没有当前武将的数据,才进行解析 var giftdict = ConfigParse.ParseIntArray2Dict(config.HeroGiftItemInfo); int[][] ctgArray = ctgConfig.GainItemList; foreach (var kvp in giftdict) { int hId = kvp.Key; int[][] hGift = kvp.Value ?? Array.Empty<int[]>(); dict[hId] = hGift.Concat(ctgArray).ToArray(); } // 如果遍历完发现配表里根本没有这个 heroID if (!dict.TryGetValue(heroID, out arr)) { arr = ctgArray; dict[heroID] = arr; } } return true; } /// <summary> /// 0 - 未解锁 1 - 可领取 2 - 已领取 /// </summary> public int GetStarUpFreeState(int id) { var config = ActHeroAppearStarConfig.Get(id); if (config == null) return 0; int heroId = GetCurrentDisplayStarUpHeroId(); var heroConfig = HeroConfig.Get(heroId); if (heroConfig == null) return 0; // 没锁定的武将视为未解锁 if (!IsLockStarHero(GetOperationHeroAppearInfo())) return 0; // 没获得武将本体不可领取 if (!HeroManager.Instance.HasHero(heroId)) return 0; if (IsStarUpFreeHave(starHeroIndex, config.AwardIndex)) return 2; if (IsHeroStarCntOk(heroConfig.HeroID, config.NeedStar)) return 1; return 0; } private bool IsStarUpFreeHave(int starHeroIndex, int awardIndex) { if (!starFreeAwardDict.TryGetValue(starHeroIndex, out uint freeAward)) return false; return ((freeAward >> awardIndex) & 1u) == 1u; } public bool IsHeroStarCntOk(int heroId, int needStar) { return GetNowHeroMaxStarCnt(heroId) >= needStar; } public int GetNowHeroMaxStarCnt(int heroId) { int res = 0; foreach (var item in HeroManager.Instance.GetHeroList()) { if (item == null) continue; if (item.heroId == heroId) { if (res < item.heroStar) res = item.heroStar; } } return res; } public bool TryGetStarUpStateIndex(int starGiftTempID, int tarState, out int index) { index = 0; var list = ActHeroAppearStarConfig.GetHeroReturnAwardIndexSortList(starGiftTempID); if (list == null) return false; for (int i = 0; i < list.Count; i++) { var awardIndex = list[i]; var config = ActHeroAppearStarConfig.GetConfig(starGiftTempID, awardIndex); if (config == null) continue; int state = GetStarUpFreeState(config.ID); if (state == tarState) { index = i; return true; } } return false; } public int GetStarUpJumpIndex(int starGiftTempID) { // 优先查找可领取的奖励 if (TryGetStarUpStateIndex(starGiftTempID, 1, out int index)) return index; // 若没有可领取的,则查找未达到条件的奖励 if (TryGetStarUpStateIndex(starGiftTempID, 0, out index)) return index; // 都没有 return 0; } public bool HasStarUpCanHave() { var act = GetOperationHeroAppearInfo(); if (act == null) return false; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return false; int starGiftTempID = config.StarGiftTempID; return TryGetStarUpStateIndex(starGiftTempID, 1, out _); } #endregion #region 兑换商店 private string ShopVisitTimeDataKey { get { return $"HeroReturnManager_ShopVisitTime_{PlayerDatas.Instance.PlayerId}"; } } private int LoadShopVisitTimeData() { return LocalSave.GetInt(ShopVisitTimeDataKey); } public void SaveShopVisitTimeData() { LocalSave.SetInt(ShopVisitTimeDataKey, TimeUtility.AllSeconds); } public bool IsShopVisitedToday { get { int lastVisitTime = LoadShopVisitTimeData(); int todayStartTime = TimeUtility.GetTodayStartTick(); return lastVisitTime >= todayStartTime; } } #endregion #region 皇权礼包 //没售罄 public bool IsCanBuyToday(int ctgID) { CTGConfig config = CTGConfig.Get(ctgID); if (config == null) return false; if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount)) return false; if (config.DailyBuyCount == 0) return true; return rechargeCount.todayCount < config.DailyBuyCount; } public bool IsNoSellOutCTGID(int ctgID) { CTGConfig config = CTGConfig.Get(ctgID); if (config == null) return false; if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount)) return false; return rechargeCount.totalCount < config.TotalBuyCount; } // 免费商品 public bool IsFreeShop(int shopID) { StoreConfig config = StoreConfig.Get(shopID); if (config == null) return false; return config.MoneyNum == 0; } //没售罄 public bool IsNoSellOutShopID(int shopID) { StoreConfig config = StoreConfig.Get(shopID); if (config == null) return false; StoreModel.Instance.TryGetIsSellOut(config, out int remainNum); return remainNum > 0; } public List<HeroReturnGiftItem> GetGiftItemList(bool isSort = false) { var act = GetOperationHeroAppearInfo(); if (act == null) return null; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return null; List<HeroReturnGiftItem> res = new List<HeroReturnGiftItem>(); var list = StoreModel.Instance.storeTypeDict[config.GiftShopType]; if (!list.IsNullOrEmpty()) { for (int i = 0; i < list.Count; i++) { var item = list[i]; if (item.storeConfig == null) continue; res.Add(new HeroReturnGiftItem { type = 0, id = item.storeConfig.ID, }); } } if (config.GiftCTGIDList != null) { for (int i = 0; i < config.GiftCTGIDList.Length; i++) { var item = config.GiftCTGIDList[i]; res.Add(new HeroReturnGiftItem { type = 1, id = item, }); } } if (isSort) { res = res.OrderBy(item => { bool isCanBuy = item.type == 0 ? IsNoSellOutShopID(item.id) : IsCanBuyToday(item.id); return !isCanBuy; }) .ThenBy(item => item.type) .ThenBy(item => item.id) .ToList(); } return res; } public bool HasGiftCanHave() { var list = GetGiftItemList(false); if (list.IsNullOrEmpty()) return false; for (int i = 0; i < list.Count; i++) { var item = list[i]; if (item.type == 0) { bool isFree = IsFreeShop(item.id); bool isCanBuy = IsNoSellOutShopID(item.id); if (isFree && isCanBuy) return true; } } return false; } #endregion #region 招募 public int ToInt(OperationDate date) { return date.year * 10000 + date.month * 100 + date.day; } private string GetCallSkipKey(int cfgID, OperationDate startDate, OperationDate endDate) { return string.Concat("HeroReturnManager_CallSkip_", cfgID, "_", ToInt(startDate), "_", ToInt(endDate), "_", PlayerDatas.Instance.PlayerId); } public bool LoadCallSkipData(int cfgID, OperationDate startDate, OperationDate endDate) { return LocalSave.GetBool(GetCallSkipKey(cfgID, startDate, endDate)); } public void SaveCallSkipData(int cfgID, OperationDate startDate, OperationDate endDate, bool value) { LocalSave.SetBool(GetCallSkipKey(cfgID, startDate, endDate), value); } /// <summary> /// 当前招募选中的武将ID /// </summary> public int GetCurrentDisplayCallHeroId() { var act = GetOperationHeroAppearInfo(); if (act == null) return 0; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null || config.ActHeroIDList?.Length <= callHeroIndex) return 0; return config.ActHeroIDList[callHeroIndex]; } public int GetFirstHeroId() { var act = GetOperationHeroAppearInfo(); if (act == null) return 0; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null || config.ActHeroIDList.IsNullOrEmpty()) return 0; return config.ActHeroIDList.First(); } private string GetCallChooseHeroStateKey(OperationHeroAppearInfo act) { if (act == null) return string.Empty; return string.Concat("HeroReturnManager_CallChooseHero_", act.CfgID, "_", ToInt(act.startDate), "_", ToInt(act.startDate), "_", PlayerDatas.Instance.PlayerId); } public bool LoadCallChooseHeroStateKey(OperationHeroAppearInfo act) { return LocalSave.GetBool(GetCallChooseHeroStateKey(act)); } public void SaveCallChooseHeroStateKey(OperationHeroAppearInfo act) { LocalSave.SetBool(GetCallChooseHeroStateKey(act), true); } #endregion #region 时装特卖 public event Action OnCurrentChooseSkinIDChangeEevent; private int m_currentChooseSkinID = 0; public int currentChooseSkinID { get { return m_currentChooseSkinID; } set { if (m_currentChooseSkinID == value) return; m_currentChooseSkinID = value; OnCurrentChooseSkinIDChangeEevent?.Invoke(); } } /// <summary> /// 通过skinID获取对应的heroID /// </summary> public int GetHeroIDBySkinID(int skinID) { foreach (var heroConfig in HeroConfig.GetValues()) { if (heroConfig.SkinIDList != null && heroConfig.SkinIDList.Contains(skinID)) { return heroConfig.HeroID; } } return 0; } /// <summary> /// 获取skinID在HeroConfig.SkinIDList中的索引 /// </summary> public int GetSkinIndexInHeroConfig(int heroID, int skinID) { var heroConfig = HeroConfig.Get(heroID); if (heroConfig?.SkinIDList == null) return int.MaxValue; for (int i = 0; i < heroConfig.SkinIDList.Length; i++) { if (heroConfig.SkinIDList[i] == skinID) return i; } return int.MaxValue; } //<skinID,ctgID> Dictionary<int, int> ctgDict = new(); public int GetCtgIDBySkinID(int skinID) { if (ctgDict.IsNullOrEmpty()) { GetSkinIDToCtgIDDict(); } int ctgID; ctgDict.TryGetValue(skinID, out ctgID); return ctgID; } Dictionary<int, int> GetSkinIDToCtgIDDict() { if (!ctgDict.IsNullOrEmpty()) { return ctgDict; } foreach (var config in ActHeroAppearConfig.GetValues()) { if (config == null || config.SkinCTGIDList == null) return null; for (int i = 0; i < config.SkinCTGIDList.Length; i++) { var ctgID = config.SkinCTGIDList[i]; var ctgConfig = CTGConfig.Get(ctgID); if (ctgConfig == null || ctgConfig.GainItemList == null) continue; for (int j = 0; j < ctgConfig.GainItemList.Length; j++) { var itemID = ctgConfig.GainItemList[j][0]; var itemConfig = ItemConfig.Get(itemID); if (itemConfig == null) continue; if (!HeroSkinAttrConfig.TryGetSkinIDByItemID(itemID, out var skinID)) continue; if (ctgDict.ContainsKey(skinID)) continue; ctgDict[skinID] = ctgID; } } } return ctgDict; } public bool HasItemInSkinCTGIDList(int cfgID, int findItemID) { var config = ActHeroAppearConfig.Get(cfgID); if (config == null || config.SkinCTGIDList == null) return false; for (int i = 0; i < config.SkinCTGIDList.Length; i++) { var ctgID = config.SkinCTGIDList[i]; var ctgConfig = CTGConfig.Get(ctgID); if (ctgConfig == null || ctgConfig.GainItemList == null) continue; for (int j = 0; j < ctgConfig.GainItemList.Length; j++) { var itemID = ctgConfig.GainItemList[j][0]; if (itemID == findItemID) return true; } } return false; } public List<int> GetSkinIDList(int cfgID, int heroID, int mainSkinID) { var config = ActHeroAppearConfig.Get(cfgID); if (config == null || config.SkinCTGIDList == null) return null; var res = new List<int>(); for (int i = 0; i < config.SkinCTGIDList.Length; i++) { var ctgID = config.SkinCTGIDList[i]; var ctgConfig = CTGConfig.Get(ctgID); if (ctgConfig == null || ctgConfig.GainItemList == null) continue; for (int j = 0; j < ctgConfig.GainItemList.Length; j++) { var itemID = ctgConfig.GainItemList[j][0]; var itemConfig = ItemConfig.Get(itemID); if (itemConfig == null) continue; if (!HeroSkinAttrConfig.TryGetSkinIDByItemID(itemID, out var skinID)) continue; if (res.Contains(skinID)) continue; res.Add(skinID); } } // 自定义排序 res.Sort((a, b) => { // 1. 判断是否是传入heroID的皮肤,优先排前面 int heroIDA = GetHeroIDBySkinID(a); int heroIDB = GetHeroIDBySkinID(b); bool isPriorityA = (heroIDA == heroID); bool isPriorityB = (heroIDB == heroID); if (isPriorityA != isPriorityB) return isPriorityA ? -1 : 1; // 2. 相同武将的多个皮肤连续挨在一起 if (heroIDA != heroIDB) return heroIDA.CompareTo(heroIDB); // 3. 如果heroid相同,和MainSkinID相同的排在最前面 if (a == mainSkinID) return -1; if (b == mainSkinID) return 1; // 4. 其他按SkinIDList索引排序 int indexA = GetSkinIndexInHeroConfig(heroIDA, a); int indexB = GetSkinIndexInHeroConfig(heroIDB, b); return indexA.CompareTo(indexB); }); return res; } #endregion #region 获奖记录 public static readonly int RecordType = 311; public void SendViewGameRecPack(int treasureType) { CA008_tagCSViewGameRec pack = new CA008_tagCSViewGameRec(); pack.RecType = (ushort)RecordType; pack.RecID = (uint)treasureType; GameNetSystem.Instance.SendInfo(pack); } public bool isSendFirst = true; List<HeroReturnGameRec> gameRecDict = new(); public List<HeroReturnGameRec> GetGameRecList() { return gameRecDict; } public event Action OnUpdateGameRecInfo; public void UpdateGameRecInfo(HA009_tagSCGameRecInfo vNetData) { var act = GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int treasureType = config.ActTreasureType; if (vNetData.RecType != RecordType || treasureType != (int)vNetData.RecID) return; if (vNetData.RecList.IsNullOrEmpty()) return; if (isSendFirst) { gameRecDict.Clear(); } foreach (var rec in vNetData.RecList) { try { var playerName = JsonMapper.ToObject(rec.UserData)["Name"].ToString(); var arenaGameRec = new HeroReturnGameRec { Time = (int)rec.Time, ItemID = (int)rec.Value1, ItemCount = rec.Value2, PlayerID = (int)rec.Value3, ServerID = (int)rec.Value4, PlayerName = playerName, }; gameRecDict.Add(arenaGameRec); } catch (Exception ex) { Debug.LogError($"JSON解析错误: {ex.Message}, UserData: {rec.UserData}"); continue; } } if (isSendFirst) { isSendFirst = !isSendFirst; gameRecDict.Sort((x, y) => x.Time.CompareTo(y.Time)); } OnUpdateGameRecInfo?.Invoke(); } #endregion } public class HeroReturnGiftItem { public int type;//0 商店id 1 充值id public int id; } public enum HeroReturnRedPointType { CheckIn = 1, StarUp = 2, Shop = 3, Gift = 4, } public class HeroReturnGameRec { public int Time; public int ItemID; public long ItemCount; public int PlayerID; public int ServerID; public string PlayerName; } Main/System/HeroReturn/HeroReturnManager.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: b509add974a70944ea78b2739e505c32 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnPopWin.cs
New file @@ -0,0 +1,96 @@ using UnityEngine; using UnityEngine.UI; public class HeroReturnPopWin : UIBase { [SerializeField] ImageEx bgImage; [SerializeField] UIHeroController rolelhShow; [SerializeField] ImageEx qaulityBgImage; [SerializeField] ImageEx qaulityImage; [SerializeField] ButtonEx goButton; [SerializeField] ImageEx titleBgImage; [SerializeField] ImageEx titleImage; [SerializeField] ImageEx infoBgImage; [SerializeField] UIEffectPlayer uiEffectPlayer; [SerializeField] TextEx infoText; [SerializeField] TextEx timeText; [SerializeField] Toggle todayPopToggle; [SerializeField] ButtonEx closeButton; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); goButton.SetListener(() => { UIManager.Instance.CloseWindow<HeroReturnPopWin>(); if (!UIManager.Instance.IsOpened<HeroReturnWin>()) UIManager.Instance.OpenWindow<HeroReturnWin>(); }); todayPopToggle.AddListener((bool value) => { if (value) manager.SavePopTimeData(); }); } protected override void OnPreOpen() { GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; Display(); } protected override void OnPreClose() { GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; } private void OnSecondEvent() { manager.GetActTimeStr(timeText, "HeroDebutPop02"); } private void Display() { uiEffectPlayer.Stop(); todayPopToggle.isOn = !manager.IsTodayPop; int heroID = manager.GetFirstHeroId(); var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; var heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return; int skinID = manager.GetDefaultSkinID(heroID); var skinConfig = HeroSkinConfig.Get(skinID); if (skinConfig == null) return; uiEffectPlayer.effectId = artConfig.PopInfoBgUIEffectId; uiEffectPlayer.Play(); bgImage.SetSprite(artConfig.PopBgImage); bgImage.SetNativeSize(); qaulityBgImage.SetSprite($"HeroDebutPopQaulityBG{heroConfig.Quality}"); qaulityBgImage.SetNativeSize(); qaulityImage.SetSprite($"HeroDebutPopQaulity{heroConfig.Quality}"); qaulityImage.SetNativeSize(); titleBgImage.SetSprite(artConfig.PopTitleBgImage); titleBgImage.SetNativeSize(); titleImage.SetSprite(artConfig.PopTitleImage); titleImage.SetNativeSize(); infoBgImage.SetSprite(artConfig.PopInfoBgImage); infoBgImage.SetNativeSize(); infoText.text = artConfig.PopInfoText; infoText.color = manager.ParseColor32(artConfig.PopInfoColor); rolelhShow.Create(skinID, 1, motionName: "", isLh: true); OnSecondEvent(); } } Main/System/HeroReturn/HeroReturnPopWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 2ec133afd45ed6548bf892a3179cba58 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnRankAwardCell.cs
New file @@ -0,0 +1,45 @@ using UnityEngine; public class HeroReturnRankAwardCell : CellView { [SerializeField] ImageEx imgRank; [SerializeField] TextEx txtRank; [SerializeField] ItemCell[] itemCells; public void Display(int rankA, int templateID) { var config = ActBillboardAwardConfig.GetConfig(templateID, rankA); if (config == null) return; if (rankA <= 3) { imgRank.SetActive(true); txtRank.SetActive(false); imgRank.SetSprite(StringUtility.Concat("Rank", rankA.ToString())); txtRank.text = rankA.ToString(); } else { imgRank.SetActive(false); txtRank.SetActive(true); txtRank.text = Language.Get("Arena15", rankA, config.RankB); } int[][] rewardArr = config.AwardItemList; for (int i = 0; i < itemCells.Length; i++) { var itemCell = itemCells[i]; if (!rewardArr.IsNullOrEmpty() && i < rewardArr.Length) { int itemCellIndex = i; itemCell.SetActive(true); itemCell.Init(new ItemCellModel(rewardArr[i][0], true, rewardArr[i][1])); itemCell.button.SetListener(() => ItemTipUtility.Show(rewardArr[itemCellIndex][0], true)); } else { itemCell.SetActive(false); } } } } Main/System/HeroReturn/HeroReturnRankAwardCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 31c2c107b8558ce4db4c8208a7019236 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnRankCell.cs
New file @@ -0,0 +1,76 @@ using UnityEngine; using UnityEngine.UI; public class HeroReturnRankCell : MonoBehaviour { [SerializeField] AvatarCell avatarCell; [SerializeField] Text rankText; [SerializeField] Text rankValueText; //排名比较内容 [SerializeField] Text nameText; [SerializeField] OfficialTitleCell officialTitleCell; [SerializeField] Button queryPlayerBtn; //后续添加点击查看玩家详情 HeroReturnManager manager => HeroReturnManager.Instance; // rank 为0 代表玩家自己 public void Display(int rankType, int rank, string valueFormat) { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int billTempID = config.BillTempID; var awardConfig = ActBillboardAwardConfig.GetConfig(billTempID, rank); RankData rankData = null; int viewPlayerId = (int)PlayerDatas.Instance.baseData.PlayerID; if (rank != 0) { rankData = RankModel.Instance.GetRankDataByRank(rankType, rank); } else { rankData = RankModel.Instance.GetMyRank(rankType); if (rankData == null) { //取玩家自己的数据 avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID, PlayerDatas.Instance.baseData.face, PlayerDatas.Instance.baseData.facePic)); rankText.text = Language.Get("L1045"); rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut27", awardConfig.NeedValue); nameText.text = PlayerDatas.Instance.baseData.PlayerName; officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID); return; } rank = rankData.rank; } if (rankData == null) { officialTitleCell.SetActive(false); avatarCell.SetActive(false); nameText.text = Language.Get("L1124"); rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut27", awardConfig.NeedValue); } else { officialTitleCell.SetActive(true); officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2); avatarCell.SetActive(true); avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4)); viewPlayerId = (int)rankData.id; nameText.text = rankData.name1; rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue)); } rankText.text = rank.ToString(); if (queryPlayerBtn != null) { queryPlayerBtn.AddListener(() => { AvatarHelper.TryViewOtherPlayerInfo(viewPlayerId); }); } } } Main/System/HeroReturn/HeroReturnRankCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: a9a73b5eecf896f46a562a01b9102ba6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnRankTop3Cell.cs
New file @@ -0,0 +1,47 @@ using UnityEngine; using UnityEngine.UI; public class HeroReturnRankTop3Cell : MonoBehaviour { //[SerializeField] Model 显示NPC 武将模型 [SerializeField] Text rankValueText; //排名比较内容 [SerializeField] Text nameText; [SerializeField] OfficialTitleCell officialTitleCell; [SerializeField] Button queryPlayerBtn; //后续添加点击查看玩家详情 [SerializeField] HorseController model; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int rankType, int rank, string valueFormat = "{0}") { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int billTempID = config.BillTempID; var awardConfig = ActBillboardAwardConfig.GetConfig(billTempID, rank); var rankData = RankModel.Instance.GetRankDataByRank(rankType, rank); if (rankData == null) { rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut40", awardConfig.NeedValue); nameText.text = Language.Get("L1124"); officialTitleCell.SetActive(false); model.SetActive(false); return; } officialTitleCell.SetActive(true); rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue)); nameText.text = rankData.name1; officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2); model.SetActive(true); model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f); queryPlayerBtn.SetListener(() => { AvatarHelper.TryViewOtherPlayerInfo((int)rankData.id); }); } } Main/System/HeroReturn/HeroReturnRankTop3Cell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e3f3dcdd709d3ab4e918517695fb715a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnRankWin.cs
New file @@ -0,0 +1,175 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnRankWin : FunctionsBaseWin { [SerializeField] ButtonEx btnClose; [SerializeField] RectTransform rankRect; [SerializeField] RectTransform awardRect; [SerializeField] TextEx timeText; [Header("排行")] [SerializeField] ScrollerController rankScroller; [SerializeField] List<HeroReturnRankTop3Cell> playerTop3Cells; [SerializeField] HeroReturnRankCell myRankCell; [HideInInspector] public string valueFormat = "{0}"; [Header("奖励")] // [SerializeField] TextEx txtCountdown; [SerializeField] ScrollerController awardScroller; [SerializeField] ImageEx heroImage; [SerializeField] TextEx myRankNumText; [SerializeField] TextEx myCallCntText; [SerializeField] TextEx timeText1; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { base.InitComponent(); btnClose.SetListener(CloseWindow); } protected override void OnPreOpen() { base.OnPreOpen(); RankModel.Instance.ResetQueryParam(); RankModel.Instance.QueryRankByPage(manager.sendRankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID, groupValue1: manager.actNum); RankModel.Instance.onRankRefresh += OnRankRefresh; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; rankScroller.OnRefreshCell += OnRefreshCell; awardScroller.OnRefreshCell += OnRefreshAwardCell; Display(); } protected override void OnPreClose() { base.OnPreClose(); RankModel.Instance.onRankRefresh -= OnRankRefresh; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; rankScroller.OnRefreshCell -= OnRefreshCell; awardScroller.OnRefreshCell -= OnRefreshAwardCell; } void OnRankRefresh(int type) { RankRefresh(); } void RankRefresh() { ShowTop3(); rankScroller.m_Scorller.RefreshActiveCellViews(); DisplayMyRank(); DisplayAwardMyRank(); } void CreateRankScroller() { rankScroller.Refresh(); var cnt = RankModel.Instance.GetRankShowMaxCnt(manager.sendRankType); for (int i = 3; i < cnt; i++) { rankScroller.AddCell(ScrollerDataType.Header, i); } rankScroller.Restart(); } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroReturnRankCell>(); _cell.Display(manager.loadRankType, cell.index + 1, valueFormat); RankModel.Instance.ListenRankPage(manager.sendRankType, cell.index, groupValue1: manager.actNum); } private void OnSecondEvent() { manager.GetActTimeStr(timeText); manager.GetActTimeStr(timeText1); } protected override void OpenSubUIByTabIndex() { rankRect.SetActive(functionOrder == 0); awardRect.SetActive(functionOrder == 1); Display(); } public void Display() { int heroID = manager.GetFirstHeroId(); var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; if (functionOrder == 0) { ShowTop3(); CreateRankScroller(); DisplayMyRank(); } else { CreateAwardScroller(); heroImage.SetSprite(artConfig.RankAwardHeroImage); heroImage.SetNativeSize(); DisplayAwardMyRank(); } OnSecondEvent(); } private void DisplayMyRank() { myRankCell.Display(manager.loadRankType, 0, valueFormat); } void ShowTop3() { for (int i = 0; i < playerTop3Cells.Count; i++) { playerTop3Cells[i].Display(manager.loadRankType, i + 1); } } void DisplayAwardMyRank() { RankData rankData = RankModel.Instance.GetMyRank(manager.loadRankType); if (rankData == null) { myRankNumText.text = Language.Get("L1045"); myCallCntText.text = "0"; return; } myRankNumText.text = Language.Get("WarlordPavilion12", rankData.rank); myCallCntText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue)); } int billTempID; private void CreateAwardScroller() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; billTempID = config.BillTempID; var list = ActBillboardAwardConfig.GetRankASortList(billTempID); if (list == null) return; awardScroller.Refresh(); for (int i = 0; i < list.Count; i++) { awardScroller.AddCell(ScrollerDataType.Header, list[i]); } awardScroller.Restart(); } private void OnRefreshAwardCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroReturnRankAwardCell>(); _cell?.Display(cell.index, billTempID); } } Main/System/HeroReturn/HeroReturnRankWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 564897474a653594fbb6f294779e17c1 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnShopCell.cs
New file @@ -0,0 +1,134 @@ using UnityEngine; using UnityEngine.UI; public class HeroReturnShopCell : MonoBehaviour { [SerializeField] Transform saleRect; [SerializeField] Text saleText; [SerializeField] Text itemName; [SerializeField] ItemCell itemCell; [SerializeField] Text limitText; [SerializeField] Text lockTip; [SerializeField] Transform priceRect; [SerializeField] Image priceIcon; [SerializeField] Text priceText; [SerializeField] Transform priceRect1;//居中位置的价格 [SerializeField] Image priceIcon1; [SerializeField] Text priceText1; [SerializeField] Transform salePriceRect; [SerializeField] Text salePriceText; [SerializeField] Button buyButton; [SerializeField] Image freeRedPoint; [SerializeField] Text freeText; [SerializeField] Image exclusiveImage;//专属 [SerializeField] Image sellOutImage;//售罄 HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int index) { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ExShopType, out var list)) return; var storeData = list[index]; int shopID = storeData.shopId; var itemID = storeData.storeConfig.ItemID; var itemCount = storeData.storeConfig.ItemCnt; exclusiveImage.SetActive(storeData.storeConfig.IsExclusive == 1); itemCell.Init(new ItemCellModel(itemID, false, itemCount)); itemCell.button.AddListener(() => { ItemTipUtility.Show(itemID); }); var itemConfig = ItemConfig.Get(itemID); itemName.text = itemConfig.ItemName; //折扣 if (storeData.storeConfig.MoneyOriginal != 0) { saleRect.SetActive(true); saleText.text = Language.Get("storename5", (storeData.storeConfig.MoneyNum * 10 / (float)storeData.storeConfig.MoneyOriginal).ToString("0.#")); } else { saleRect.SetActive(false); } var buyCnt = StoreModel.Instance.GetShopLimitBuyCount(shopID); string limitStr = ""; if (storeData.storeConfig.MoneyNum == 0) { //免费 limitStr = ""; } else if (storeData.storeConfig.ResetType == 0) { //限购 limitStr = storeData.storeConfig.LimitCnt > 0 ? Language.Get("storename8", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt) : ""; } else if (storeData.storeConfig.ResetType == 1) { //每日限购 limitStr = Language.Get("storename6", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt); } else if (storeData.storeConfig.ResetType == 2) { //每周限购 limitStr = Language.Get("storename7", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt); } limitText.text = buyCnt >= storeData.storeConfig.LimitCnt ? UIHelper.AppendColor(TextColType.Gray, limitStr) : limitStr; buyButton.AddListener(() => { BuyGoods(shopID); }); //0可购买 1已售罄 2免费 3未解锁 var state = StoreModel.Instance.GetShopIDState(shopID); sellOutImage.SetActive(state == 1); freeRedPoint.SetActive(state == 2); lockTip.text = state == 2 ? Language.Get("storename10", storeData.storeConfig.UnlockValue) : string.Empty; priceRect.SetActive(state != 2 && storeData.storeConfig.MoneyOriginal != 0); priceRect1.SetActive(state != 2 && storeData.storeConfig.MoneyOriginal == 0); freeText.SetActive(state == 2); salePriceRect.SetActive(state != 2 && storeData.storeConfig.MoneyOriginal != 0); priceText.text = storeData.storeConfig.MoneyNum.ToString(); priceText1.text = storeData.storeConfig.MoneyNum.ToString(); if (storeData.storeConfig.MoneyType <= 0) { priceIcon.SetItemSprite(storeData.storeConfig.CostItemID); priceIcon1.SetItemSprite(storeData.storeConfig.CostItemID); } else { priceIcon.SetIconWithMoneyType(storeData.storeConfig.MoneyType); priceIcon1.SetIconWithMoneyType(storeData.storeConfig.MoneyType); } salePriceText.text = storeData.storeConfig.MoneyOriginal.ToString(); } void BuyGoods(int shopID) { var state = StoreModel.Instance.GetShopIDState(shopID); if (state == 1) return; if (state == 2) { StoreModel.Instance.SendBuyShopItem(StoreConfig.Get(shopID), 1); } else { StoreModel.Instance.buyShopID = shopID; UIManager.Instance.OpenWindow<BuyItemWin>(); } } } Main/System/HeroReturn/HeroReturnShopCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 9f3fa1a06f369cd43bfeed05c9fc78da MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnShopLineCell.cs
New file @@ -0,0 +1,30 @@ using UnityEngine; public class HeroReturnShopLineCell : CellView { [SerializeField] HeroReturnShopCell[] storeCells; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int index) { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ExShopType, out var list)) return; for (int i = 0; i < storeCells.Length; i++) { if (index + i < list.Count) { storeCells[i].SetActive(true); storeCells[i].Display(index + i); } else { storeCells[i].SetActive(false); } } } } Main/System/HeroReturn/HeroReturnShopLineCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 7dbf46352446602458ece7d5acde3f20 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnShopWin.cs
New file @@ -0,0 +1,80 @@ using UnityEngine; public class HeroReturnShopWin : UIBase { [SerializeField] OwnItemCell ownItemCell; [SerializeField] ButtonEx closeButton; [SerializeField] TextEx timeText; [SerializeField] ScrollerController scroller; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; StoreModel.Instance.RefreshShopEvent += CreateScroller; StoreModel.Instance.RefreshBuyShopLimitEvent += CreateScroller; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; if (!manager.IsShopVisitedToday) { HeroReturnManager.Instance.SaveShopVisitTimeData(); manager.UpdateRedpoint(); } var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; ownItemCell.itemID = config.ExShopCostItemID; CreateScroller(); OnSecondEvent(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; StoreModel.Instance.RefreshShopEvent -= CreateScroller; StoreModel.Instance.RefreshBuyShopLimitEvent -= CreateScroller; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal; } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnShopLineCell; _cell.Display(cell.index); } private void OnSecondEvent() { manager.GetActTimeStr(timeText); } void CreateScroller() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ExShopType, out var list)) return; scroller.Refresh(); for (int i = 0; i < list.Count; i++) { if (i % 3 == 0) { scroller.AddCell(ScrollerDataType.Header, i); } } scroller.Restart(); scroller.lockType = EnhanceLockType.KeepVertical; } } Main/System/HeroReturn/HeroReturnShopWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: fceb72924bf0d6c418f2128afc294a52 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnSkinAwardCell.cs
New file @@ -0,0 +1,18 @@ using UnityEngine; public class HeroReturnSkinAwardCell : CellView { [SerializeField] ItemCell itemCell; public void Display(int index, int[][] arr) { if (arr == null || arr.Length <= index) return; int itemID = arr[index][0]; long itemCount = arr[index][1]; itemCell.Init(new ItemCellModel(itemID, false, itemCount)); itemCell.button.AddListener(() => { ItemTipUtility.Show(itemID); }); } } Main/System/HeroReturn/HeroReturnSkinAwardCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: f6b0d10c152793d4f81f3b5fe4182937 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnSkinTabCell.cs
New file @@ -0,0 +1,28 @@ using System.Collections.Generic; using UnityEngine; public class HeroReturnSkinTabCell : CellView { [SerializeField] ImageEx tabBgImage; [SerializeField] ButtonEx tabButton; [SerializeField] RectTransform chooseRect; [SerializeField] RectTransform maskRect; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int index, List<int> list) { if (list?.Count <= index) return; var skinID = list[index]; var skinArtConfig = ActHeroReturnSkinArtConfig.Get(skinID); if (skinArtConfig == null) return; tabBgImage.SetSprite(skinArtConfig.TabInfoImage); tabBgImage.SetNativeSize(); maskRect.SetActive(manager.currentChooseSkinID != skinID); chooseRect.SetActive(manager.currentChooseSkinID == skinID); tabButton.SetListener(() => { manager.currentChooseSkinID = skinID; }); } } Main/System/HeroReturn/HeroReturnSkinTabCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 4f356ffc491c15044879e4d6601e5726 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnSkinWin.cs
New file @@ -0,0 +1,229 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HeroReturnSkinWin : UIBase { [SerializeField] float modelScale = 1f; [SerializeField] RawImage bgImage; [SerializeField] ImageEx heroNameImage; [SerializeField] ImageEx skinInfoImage; [SerializeField] ImageEx awardBgImage; [SerializeField] TextEx timeText; [SerializeField] ButtonEx buyButton; [SerializeField] ImageEx buyImage; [SerializeField] ImageEx countryImage; [SerializeField] TextEx buyText; [SerializeField] ButtonEx closeButton; [SerializeField] UIHeroController uiHeroController; [SerializeField] UIHeroController lhController; [SerializeField] ScrollerController awardScroller; [SerializeField] ScrollerController tabScroller; [SerializeField] Color numColor; [SerializeField] TextEx[] wearAttrText; [SerializeField] TextEx[] roleAttrText; [SerializeField] ButtonEx infoButton; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); infoButton.SetListener(() => { int heroID = manager.GetHeroIDBySkinID(manager.currentChooseSkinID); HeroUIManager.Instance.selectForPreviewHeroID = heroID; HeroUIManager.Instance.selectSkinIndex = manager.GetSkinIndexInHeroConfig(heroID, manager.currentChooseSkinID); UIManager.Instance.OpenWindow<HeroBestBaseWin>(1); }); } protected override void OnPreOpen() { GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; awardScroller.OnRefreshCell += OnRefreshAwardCell; tabScroller.OnRefreshCell += OnRefreshTabCell; manager.OnCurrentChooseSkinIDChangeEevent += OnCurrentChooseSkinIDChange; CreateTabScroller(); Display(); } protected override void OnPreClose() { GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent; awardScroller.OnRefreshCell -= OnRefreshAwardCell; tabScroller.OnRefreshCell -= OnRefreshTabCell; manager.OnCurrentChooseSkinIDChangeEevent -= OnCurrentChooseSkinIDChange; } private void OnCurrentChooseSkinIDChange() { tabScroller.m_Scorller.RefreshActiveCellViews(); Display(); } void OnRefreshTabCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnSkinTabCell; _cell.Display(cell.index, skinIDList); } List<int> skinIDList; void CreateTabScroller() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int heroID = manager.GetFirstHeroId(); var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; skinIDList = manager.GetSkinIDList(act.CfgID, heroID, artConfig.MainSkinID); if (skinIDList.IsNullOrEmpty()) return; manager.currentChooseSkinID = skinIDList[0]; tabScroller.Refresh(); for (int i = 0; i < skinIDList.Count; i++) { tabScroller.AddCell(ScrollerDataType.Header, i); } tabScroller.Restart(); } int[][] arr = null; void OnRefreshAwardCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnSkinAwardCell; _cell.Display(cell.index, arr); } void CreateAwardScroller(int[][] sourceArr) { if (sourceArr == null) return; // 1. 获取已拥有的 ID 集合 (使用 LINQ 简洁明了) var ownedItems = HeroSkinAttrConfig.GetItemList(); var itemIds = ownedItems != null ? new HashSet<int>(ownedItems) : new HashSet<int>(); // 2. 过滤掉 items 中已有的项,并直接赋值给成员变量 // arr[i][0] 假设为判断是否存在于 items 中的 ID this.arr = System.Array.FindAll(sourceArr, row => !itemIds.Contains(row[0])); // 3. 刷新 UI awardScroller.Refresh(); for (int i = 0; i < this.arr.Length; i++) { awardScroller.AddCell(ScrollerDataType.Header, i); } awardScroller.Restart(); } private void OnSecondEvent() { manager.GetActTimeStr(timeText); } private void OnRechargeCountEvent(int obj) { Display(); } public void Display() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; int heroID = manager.GetFirstHeroId(); var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; var heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return; int skinID = manager.currentChooseSkinID; var skinArtConfig = ActHeroReturnSkinArtConfig.Get(skinID); if (skinArtConfig == null) return; var heroSkinAttrConfig = HeroSkinAttrConfig.Get(skinID); if (heroSkinAttrConfig == null) return; if (heroSkinAttrConfig.WearAttrIDList == null) return; if (heroSkinAttrConfig.WearAttrValueList == null) return; if (heroSkinAttrConfig.RoleAttrIDList == null) return; if (heroSkinAttrConfig.RoleAttrValueList == null) return; var skinIDList = manager.GetSkinIDList(act.CfgID, heroID, skinID); if (skinIDList.IsNullOrEmpty()) return; int ctgId = manager.GetCtgIDBySkinID(skinID); var ctgConfig = CTGConfig.Get(ctgId); if (ctgConfig == null) return; if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) return; if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) return; if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) return; bgImage.SetTexture2D(skinArtConfig.BGImage); heroNameImage.SetSprite(skinArtConfig.HeroNameImage); heroNameImage.SetNativeSize(); skinInfoImage.SetSprite(skinArtConfig.SkinInfoImage); skinInfoImage.SetNativeSize(); awardBgImage.SetSprite(skinArtConfig.AwardBGImage); awardBgImage.SetNativeSize(); uiHeroController.Create(skinID, modelScale); lhController.Create(skinID, 1, motionName: "", isLh: true); countryImage.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country)); OnSecondEvent(); CreateAwardScroller(ctgConfig.GainItemList); bool isCanBuy = manager.IsNoSellOutCTGID(ctgId); //buyImage.gray = !isCanBuy; buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale)); buyButton.interactable = isCanBuy; buyButton.SetListener(() => { RechargeManager.Instance.CTG(ctgId); }); for (int i = 0; i < wearAttrText.Length; i++) SetAttrInfo(0, i, heroSkinAttrConfig, wearAttrText[i]); for (int i = 0; i < roleAttrText.Length; i++) SetAttrInfo(1, i, heroSkinAttrConfig, roleAttrText[i]); } // type 0 穿戴属性值 1 主公属性 public void SetAttrInfo(int type, int index, HeroSkinAttrConfig heroSkinAttrConfig, TextEx info) { if (heroSkinAttrConfig == null) return; int[] arrID = type == 0 ? heroSkinAttrConfig.WearAttrIDList : heroSkinAttrConfig.RoleAttrIDList; int[] arrValue = type == 0 ? heroSkinAttrConfig.WearAttrValueList : heroSkinAttrConfig.RoleAttrValueList; if (arrID?.Length <= index || arrValue?.Length <= index) { info.text = string.Empty; return; } info.text = GetFullDescription(arrID[index], arrValue[index]); } string GetFullDescription(int id, long value) { var config = PlayerPropertyConfig.Get(id); if (config == null) return string.Empty; return Language.Get("HeroDebut33", config.ShowName, PlayerPropertyConfig.GetValueDescription(id, value)); } } Main/System/HeroReturn/HeroReturnSkinWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: a583b7b333d69584792f6aef8834bfcd MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnStarUpCell.cs
New file @@ -0,0 +1,126 @@ using System.Linq; using UnityEngine; public class HeroReturnStarUpCell : CellView { [SerializeField] ItemCell freeAwardItemCell; [SerializeField] Transform freeAwardHaveTransform;//已领取 [SerializeField] Transform freeAwardCanHaveTransform;//可领取 [SerializeField] Transform upProcssBGTransform; [SerializeField] Transform upProcessTransform; [SerializeField] Transform downProcssBGTransform; [SerializeField] Transform downProcessTransform; [SerializeField] TextEx starCntText; [SerializeField] TextEx limitText; [SerializeField] ButtonEx buyButton; [SerializeField] ImageEx buyImage; [SerializeField] TextEx buyText; [SerializeField] ImageEx rateImage; [SerializeField] TextEx rateText; [SerializeField] ScrollerController scroller; HeroReturnManager manager => HeroReturnManager.Instance; int id; public void Display(int id, CellView cell) { this.id = id; int heroID = cell.info.Value.infoInt1; bool isFrist = cell.info.Value.infoInt2 == 1; bool isEnd = cell.info.Value.infoInt3 == 1; var config = ActHeroAppearStarConfig.Get(id); if (config == null) return; var heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return; if (config.FreeAwardItemList.IsNullOrEmpty()) return; int ctgId = config.StarGiftCTGID; int awardIndex = config.AwardIndex; if (!manager.TryGetStarUpAwardArr(id, heroID, out int[][] list)) return; if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) return; if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) return; if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) return; CTGConfig ctgConfig = CTGConfig.Get(ctgId); if (ctgConfig == null) return; rateImage.SetActive(true); rateText.text = Language.Get("DailySpecials07", ctgConfig.Percentage); int state = manager.GetStarUpFreeState(id);//0 - 未解锁 1 - 可领取 2 - 已领取 freeAwardHaveTransform.SetActive(state == 2); freeAwardCanHaveTransform.SetActive(state == 1); bool isNoSellOut = manager.IsNoSellOutCTGID(ctgId); buyButton.interactable = state != 0 && isNoSellOut; buyButton.SetListener(() => { if (isNoSellOut && state != 0) { RechargeManager.Instance.CTG(ctgId); } }); //buyImage.gray = state == 0 || !isNoSellOut; buyText.text = !isNoSellOut ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale)); limitText.text = Language.Get("TimeRush08", UIHelper.AppendColor(rechargeCount.totalCount >= ctgConfig.TotalBuyCount ? TextColType.Red : TextColType.DarkGreen, $"{rechargeCount.totalCount}/{ctgConfig.TotalBuyCount}")); bool isHeroStarOk = manager.IsHeroStarCntOk(heroConfig.HeroID, config.NeedStar) && HeroManager.Instance.HasHero(heroConfig.HeroID) && manager.IsLockStarHero(manager.GetOperationHeroAppearInfo()); upProcssBGTransform.SetActive(!isFrist); downProcssBGTransform.SetActive(!isEnd); upProcessTransform.SetActive(isHeroStarOk); downProcessTransform.SetActive(isHeroStarOk); CreateScroller(list); int[] arr = config.FreeAwardItemList.First(); int itemID = arr[0]; int itemCount = arr[1]; freeAwardItemCell.SetActive(true); freeAwardItemCell.Init(new ItemCellModel(itemID, false, itemCount)); freeAwardItemCell.button.AddListener(() => { if (state == 1) { manager.SendGetStarReward(); } else { ItemTipUtility.Show(itemID); } }); starCntText.text = Language.Get("HeroDebut20", config.NeedStar); } private void CreateScroller(int[][] list) { if (list == null) return; var config = ActHeroAppearStarConfig.Get(id); if (config == null) return; scroller.OnRefreshCell += OnRefreshCell; scroller.Refresh(); for (int i = 0; i < list.Length; i++) { var item = list[i]; var itemID = item[0]; var itemCount = item[1]; CellInfo cellInfo = new() { infoInt1 = itemID, infoInt2 = itemCount, infoInt3 = manager.IsNoSellOutCTGID(config.StarGiftCTGID) ? 1 : 0, }; scroller.AddCell(ScrollerDataType.Header, i, cellInfo); } scroller.Restart(); scroller.OnRefreshCell -= OnRefreshCell; } private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroReturnStarUpPaidItemCell>(); _cell?.Display(cell.index, cell); } } Main/System/HeroReturn/HeroReturnStarUpCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 98c3340ec72bd5b46935ede657bae2b3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnStarUpChangeCell.cs
New file @@ -0,0 +1,33 @@ using UnityEngine; public class HeroReturnStarUpChangeCell : CellView { [SerializeField] HeroReturnStarUpChangeItem[] items; HeroReturnManager manager => HeroReturnManager.Instance; public void Display(int rowIndex) { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; var heroArr = config.ActHeroIDList; if (heroArr.IsNullOrEmpty()) return; for (int i = 0; i < items.Length; i++) { int index = rowIndex * HeroReturnCallChangeWin.rowCountMax + i; if (index < heroArr.Length) { items[i].SetActive(true); items[i].Display(index, heroArr); } else { items[i].SetActive(false); } } } } Main/System/HeroReturn/HeroReturnStarUpChangeCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 24e8dba4fdfc18547bd908c4906c29bc MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnStarUpChangeItem.cs
New file @@ -0,0 +1,41 @@ using UnityEngine; using UnityEngine.UI; public class HeroReturnStarUpChangeItem : MonoBehaviour { [SerializeField] HeroHeadBaseCell heroHeadBaseCell; [SerializeField] Image jobImg; [SerializeField] Text nameText; [SerializeField] Transform select; HeroReturnManager manager => HeroReturnManager.Instance; HeroConfig heroConfig; int index; public void Display(int index, int[] heroIds) { this.index = index; if (heroIds?.Length <= index) return; int heroId = heroIds[index]; heroConfig = HeroConfig.Get(heroId); if (heroConfig == null) return; int skinID = manager.GetDefaultSkinID(heroId); var heroSkinConfig = HeroSkinConfig.Get(skinID); if (heroSkinConfig == null) return; heroHeadBaseCell.Init(heroConfig.HeroID, skinID, 0, 0, 0, OnClick); nameText.text = heroConfig.Name; jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class)); bool isChoose = manager.nowStarUpChooseHeroID == heroId; select?.SetActive(isChoose); } public void OnClick() { if (heroConfig == null) return; manager.nowStarUpChooseHeroID = heroConfig.HeroID; } } Main/System/HeroReturn/HeroReturnStarUpChangeItem.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: f8d8ae1944679f64abb94301a00e6938 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnStarUpChangeWin.cs
New file @@ -0,0 +1,100 @@ using UnityEngine; public class HeroReturnStarUpChangeWin : UIBase { [SerializeField] ScrollerController scroller; [SerializeField] ButtonEx closeButton; [SerializeField] ButtonEx okButton; [SerializeField] ButtonEx previewButton; [SerializeField] UIHeroController uiHeroController; public const int rowCountMax = 4; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); okButton.SetListener(() => { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; int index = manager.GetHeroIdIndex(act.CfgID, manager.nowStarUpChooseHeroID); if (index < 0) return; manager.SendHeroAppearStarHeroSelect(manager.actNum, index); manager.SaveStarUpChooseHeroStateKey(act); CloseWindow(); }); previewButton.SetListener(() => { HeroUIManager.Instance.selectForPreviewHeroID = manager.nowStarUpChooseHeroID; UIManager.Instance.OpenWindow<HeroBestBaseWin>(); }); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; manager.OnNowStarUpChooseHeroIDChangeEvent += OnNowStarUpChooseHeroIDChangeEvent; manager.nowStarUpChooseHeroID = manager.GetCurrentDisplayStarUpHeroId(); Display(); CreateScroller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; manager.OnNowStarUpChooseHeroIDChangeEvent -= OnNowStarUpChooseHeroIDChangeEvent; if (!UIManager.Instance.IsOpened<HeroReturnStarUpWin>() && manager.LoadStarUpChooseHeroStateKey(manager.GetOperationHeroAppearInfo())) { UIManager.Instance.OpenWindow<HeroReturnStarUpWin>(); } } private void OnNowStarUpChooseHeroIDChangeEvent() { Display(); scroller.m_Scorller.RefreshActiveCellViews(); } void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell as HeroReturnStarUpChangeCell; _cell.Display(cell.index); } void CreateScroller() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; var arr = config.ActHeroIDList; if (arr.IsNullOrEmpty()) return; scroller.Refresh(); int rowCount = (int)Mathf.Ceil((float)arr.Length / rowCountMax); for (int i = 0; i < rowCount; i++) { scroller.AddCell(ScrollerDataType.Header, i); } scroller.Restart(); } void Display() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; int skinID = manager.GetDefaultSkinID(manager.nowStarUpChooseHeroID); var skinConfig = HeroSkinConfig.Get(skinID); if (skinConfig == null) return; uiHeroController.Create(skinID, 1); } } Main/System/HeroReturn/HeroReturnStarUpChangeWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 509bac132ac2a424fbed7f0aa2ef09de MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnStarUpPaidItemCell.cs
New file @@ -0,0 +1,17 @@ using UnityEngine; public class HeroReturnStarUpPaidItemCell : CellView { [SerializeField] ItemCell itemCell; [SerializeField] Transform soldOutTransform; public void Display(int index, CellView cell) { int itemID = cell.info.Value.infoInt1; int count = cell.info.Value.infoInt2; bool isSoldOut = cell.info.Value.infoInt3 == 0; soldOutTransform.SetActive(isSoldOut); itemCell.SetActive(true); itemCell.Init(new ItemCellModel((int)itemID, false, count)); itemCell.button.AddListener(() => ItemTipUtility.Show(itemID)); } } Main/System/HeroReturn/HeroReturnStarUpPaidItemCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: dd781838fa949c54cafb8db9df042715 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnStarUpWin.cs
New file @@ -0,0 +1,159 @@ using UnityEngine; public class HeroReturnStarUpWin : UIBase { [SerializeField] HeroHeadBaseCell heroHeadBaseCell; [SerializeField] ImageEx jobImg; [SerializeField] TextEx nameText; [SerializeField] ButtonEx changeButton; [SerializeField] ButtonEx lockButton; [SerializeField] GradientText heroNameText; [SerializeField] TextEx timeText; [SerializeField] ImageEx heroImage; [SerializeField] ButtonEx goCallButton; [SerializeField] ButtonEx goInfoButton; [SerializeField] ButtonEx closeButton; [SerializeField] ScrollerController scroller; HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(CloseWindow); goCallButton.SetListener(() => { UIManager.Instance.CloseWindow<HeroReturnStarUpWin>(); UIManager.Instance.OpenWindow<HeroReturnCallWin>(); }); goInfoButton.SetListener(() => { if (heroConfig == null) return; UIManager.Instance.CloseWindow<HeroReturnStarUpWin>(); HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID; UIManager.Instance.OpenWindow<HeroBestBaseWin>(); }); changeButton.SetListener(() => { UIManager.Instance.OpenWindow<HeroReturnStarUpChangeWin>(); }); lockButton.SetListener(() => { manager.SaveStarUpLockState(manager.GetOperationHeroAppearInfo()); Display(); manager.UpdateRedpoint(); }); } protected override void OnPreOpen() { scroller.OnRefreshCell += OnRefreshCell; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; manager.OnUpdateHeroAppearPlayerInfoEvent += OnUpdateHeroAppearPlayerInfoEvent; Display(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent; manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent; } private void OnUpdateHeroAppearPlayerInfoEvent() { scroller.m_Scorller.RefreshActiveCellViews(); Display(); } private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<HeroReturnStarUpCell>(); _cell?.Display(cell.index, cell); } private void OnSecondEvent() { manager.GetActTimeStr(timeText); } private void OnRechargeCountEvent(int obj) { scroller.m_Scorller.RefreshActiveCellViews(); } HeroConfig heroConfig; private void Display() { int heroID = manager.GetCurrentDisplayStarUpHeroId(); heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return; var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null) return; var heroArr = config.ActHeroIDList; if (heroArr.Length <= manager.starHeroIndex) return; int heroId = heroArr[manager.starHeroIndex]; heroConfig = HeroConfig.Get(heroId); if (heroConfig == null) return; int skinID = manager.GetDefaultSkinID(heroId); var heroSkinConfig = HeroSkinConfig.Get(skinID); if (heroSkinConfig == null) return; bool isLockStarHero = manager.IsLockStarHero(act); changeButton.SetActive(!isLockStarHero); lockButton.interactable = !isLockStarHero; heroHeadBaseCell.Init(heroConfig.HeroID, skinID, 0, 0, 0, () => { if (isLockStarHero) return; UIManager.Instance.OpenWindow<HeroReturnStarUpChangeWin>(); }); nameText.text = heroConfig.Name; jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class)); heroNameText.text = heroConfig.Name; manager.SetGradientTextColor(heroNameText, artConfig.HeroNameColor); heroImage.SetSprite(artConfig.StarUpHeroImage); heroImage.SetNativeSize(); CreateScroller(config, heroConfig); } private void CreateScroller(ActHeroAppearConfig appearConfig, HeroConfig heroConfig) { if (appearConfig == null || heroConfig == null) return; int starGiftTempID = appearConfig.StarGiftTempID; var list = ActHeroAppearStarConfig.GetHeroReturnAwardIndexSortList(starGiftTempID); if (list == null) return; scroller.Refresh(); for (int i = 0; i < list.Count; i++) { var awardIndex = list[i]; var config = ActHeroAppearStarConfig.GetConfig(starGiftTempID, awardIndex); if (config == null) continue; CellInfo cellInfo = new() { infoInt1 = heroConfig.HeroID, infoInt2 = i == 0 ? 1 : 0, infoInt3 = i == list.Count - 1 ? 1 : 0 }; scroller.AddCell(ScrollerDataType.Header, config.ID, cellInfo); } scroller.Restart(); scroller.JumpIndex(manager.GetStarUpJumpIndex(starGiftTempID)); } } Main/System/HeroReturn/HeroReturnStarUpWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: dae38759f25f7eb4ab53165ca393cd2e MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/HeroReturn/HeroReturnWin.cs
New file @@ -0,0 +1,268 @@ using System; using UnityEngine; using UnityEngine.UI; using DG.Tweening; public class HeroReturnWin : UIBase { [SerializeField] RectTransform activeRect; [SerializeField] RectTransform moveRect; [SerializeField] RectTransform startRect; [SerializeField] RectTransform endRect; [SerializeField] ImageEx bgImage; [SerializeField] ImageEx titleImage; [SerializeField] TextEx timeText; [SerializeField] ButtonEx animationButton; [SerializeField] ButtonEx checkInButton; // 签到赠礼 [SerializeField] RedpointBehaviour checkInRedpoint; [SerializeField] ButtonEx starUpButton; // 升星计划 [SerializeField] RedpointBehaviour starUpRedpoint; [SerializeField] ButtonEx shopButton; // 兑换商店 [SerializeField] RedpointBehaviour shopRedpoint; [SerializeField] ImageEx skinImage; [SerializeField] ButtonEx skinButton; // 时装特卖 [SerializeField] ButtonEx giftButton; // 皇权礼包 [SerializeField] RedpointBehaviour giftRedpoint; [SerializeField] ButtonEx callButton; // 皇权招募 [SerializeField] UIHeroController uiHeroController; [SerializeField] UIHeroController lhController; [SerializeField] Image callRedImage; [SerializeField] ButtonEx closeButton; [SerializeField] float modleSize = 0.8f; // 轮播相关 private const float CarouselInterval = 5f; // 轮播间隔5秒 private const float FadeDuration = 0.4f; // 渐变时长 private int[] heroIdList; // 武将ID列表 private int currentHeroIndex; // 当前武将索引 private bool isCarouselActive; // 是否正在轮播 private Tween carouselTween; // 轮播淡入淡出tween private float carouselTimer; // 轮播计时器 HeroReturnManager manager => HeroReturnManager.Instance; protected override void InitComponent() { closeButton.SetListener(() => UIManager.Instance.CloseWindow<HeroReturnWin>()); checkInButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnCheckInWin>()); starUpButton.SetListener(() => { if (manager.IsLockStarHero(manager.GetOperationHeroAppearInfo())) { UIManager.Instance.OpenWindow<HeroReturnStarUpWin>(); return; } if (!manager.LoadStarUpChooseHeroStateKey(manager.GetOperationHeroAppearInfo())) { UIManager.Instance.OpenWindow<HeroReturnStarUpChangeWin>(); return; } UIManager.Instance.OpenWindow<HeroReturnStarUpWin>(); }); shopButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnShopWin>()); skinButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnSkinWin>()); giftButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnGiftWin>()); callButton.SetListener(() => UIManager.Instance.OpenWindow<HeroReturnCallWin>()); } protected override void OnPreOpen() { InitRedpoint(); GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; StoreModel.Instance.RefreshBuyShopLimitEvent += Display; manager.OnUpdateHeroAppearPlayerInfoEvent += OnUpdateHeroAppearPlayerInfoEvent; Display(); } protected override void OnPreClose() { StopCarousel(); GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent; StoreModel.Instance.RefreshBuyShopLimitEvent -= Display; manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent; } private void OnUpdateHeroAppearPlayerInfoEvent() { Display(); } private void OnRechargeCountEvent(int obj) { Display(); } public void InitRedpoint() { checkInRedpoint.redpointId = manager.GetRedPointId(HeroReturnRedPointType.CheckIn); starUpRedpoint.redpointId = manager.GetRedPointId(HeroReturnRedPointType.StarUp); shopRedpoint.redpointId = manager.GetRedPointId(HeroReturnRedPointType.Shop); giftRedpoint.redpointId = manager.GetRedPointId(HeroReturnRedPointType.Gift); } private void Display() { var act = manager.GetOperationHeroAppearInfo(); if (act == null) return; var config = ActHeroAppearConfig.Get(act.CfgID); if (config == null || config.ActHeroIDList.IsNullOrEmpty()) return; // 获取武将列表 heroIdList = config.ActHeroIDList; currentHeroIndex = 0; // 如果只有一个武将,不轮播,直接显示 if (heroIdList.Length <= 1) { StopCarousel(); DisplayHero(heroIdList[0], false); } else { // 多个武将,开启轮播 carouselTimer = 0f; DisplayHero(heroIdList[currentHeroIndex], false); StartCarousel(); } callRedImage.SetActive(!manager.IsShopVisitedToday || manager.HasGiftCanHave()); OnSecondEvent(); } private void LateUpdate() { if (!isCarouselActive) return; if (heroIdList == null || heroIdList.Length <= 1) return; // 检查是否存在更高层级的窗口,如果有则不播放轮播 if (UIManager.Instance.ExistAnySameLevelWinHigherSortingOrder(uiLayer, uiName)) { return; } carouselTimer += Time.deltaTime; if (carouselTimer >= CarouselInterval) { carouselTimer = 0f; // 切换到下一个武将 currentHeroIndex = (currentHeroIndex + 1) % heroIdList.Length; int nextHeroID = heroIdList[currentHeroIndex]; // 带动画切换 DisplayHero(nextHeroID, true); } } /// <summary> /// 显示指定武将的背景和立绘 /// </summary> private void DisplayHero(int heroID, bool withAnimation) { var artConfig = ActHeroReturnArtConfig.Get(heroID); if (artConfig == null) return; int skinID = manager.GetDefaultSkinID(heroID); var skinConfig = HeroSkinConfig.Get(skinID); if (skinConfig == null) return; var skinArtConfig = ActHeroReturnSkinArtConfig.Get(artConfig.MainSkinID); if (skinArtConfig == null) return; if (withAnimation) { carouselTween?.Kill(); Sequence seq = DOTween.Sequence(); seq.Append(bgImage.DOFade(0.7f, FadeDuration)); CanvasGroup lhCanvasGroup = lhController.GetComponent<CanvasGroup>(); if (lhCanvasGroup == null) { lhCanvasGroup = lhController.gameObject.AddComponent<CanvasGroup>(); } seq.Join(lhCanvasGroup.DOFade(0f, FadeDuration)); seq.OnComplete(() => { UpdateHeroDisplay(heroID, skinID, artConfig, skinArtConfig); // 淡入 bgImage.DOFade(1f, FadeDuration); lhCanvasGroup.DOFade(1f, FadeDuration); }); carouselTween = seq; } else { UpdateHeroDisplay(heroID, skinID, artConfig, skinArtConfig); CanvasGroup lhCanvasGroup = lhController.GetComponent<CanvasGroup>(); if (lhCanvasGroup != null) { lhCanvasGroup.alpha = 1f; } } } /// <summary> /// 更新武将显示资源 /// </summary> private void UpdateHeroDisplay(int heroID, int skinID, ActHeroReturnArtConfig artConfig, ActHeroReturnSkinArtConfig skinArtConfig) { int chosenHeroSkinID = manager.GetDefaultSkinID( manager.LoadCallChooseHeroStateKey(manager.GetOperationHeroAppearInfo()) ? manager.GetCurrentDisplayCallHeroId() : manager.GetFirstHeroId()); uiHeroController.Create(chosenHeroSkinID, modleSize); uiHeroController.transform.localScale = new Vector3(-modleSize, modleSize, modleSize); lhController.Create(skinID, 1, motionName: "", isLh: true); // 更新背景 bgImage.SetSprite(artConfig.MainBgImage); bgImage.SetNativeSize(); // 更新标题 titleImage.SetSprite(artConfig.MainTitleImage); titleImage.SetNativeSize(); // 更新皮肤图片 int firstHeroID = manager.GetFirstHeroId(); var firstHeroIDArtConfig = ActHeroReturnArtConfig.Get(firstHeroID); if (firstHeroIDArtConfig == null) return; var firstSkinArtConfig = ActHeroReturnSkinArtConfig.Get(firstHeroIDArtConfig.MainSkinID); if (firstSkinArtConfig == null) return; skinImage.SetSprite(firstSkinArtConfig.MainSkinBuyBgImage); } /// <summary> /// 开始轮播 /// </summary> private void StartCarousel() { if (isCarouselActive) return; isCarouselActive = true; carouselTimer = 0f; } /// <summary> /// 停止轮播 /// </summary> private void StopCarousel() { isCarouselActive = false; carouselTimer = 0f; carouselTween?.Kill(); carouselTween = null; } private void OnSecondEvent() { manager.GetActTimeStr(timeText); } } Main/System/HeroReturn/HeroReturnWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 264e7ec58915d6243902eadabc46eee9 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/Main/HomeWin.cs
@@ -73,6 +73,7 @@ [SerializeField] Button osMinggeBtn; [SerializeField] TimeRushCell timeRushCell; [SerializeField] HeroDebutCell heroDebutCell; [SerializeField] HeroReturnCell heroReturnCell; //坐骑 [SerializeField] Image horseBGImg; @@ -296,6 +297,7 @@ DisplayTimeRush(); DisplayHeroDebut(); DisplayHeroReturn(); DelayPlayMusic().Forget(); } @@ -336,6 +338,10 @@ { DisplayHeroDebut(); } else if (type == OperationType.HeroReturn) { DisplayHeroReturn(); } } @@ -343,6 +349,7 @@ { DisplayTimeRush(); DisplayHeroDebut(); DisplayHeroReturn(); } private void OnShowGiftIdListAddEvent() @@ -841,6 +848,10 @@ { DisplayHeroDebut(); } else if (funcId == (int)FuncOpenEnum.HeroReturn) { DisplayHeroReturn(); } } private void OnUpdateFirstChargeInfo() @@ -917,6 +928,15 @@ return; heroDebutCell.Display(); } void DisplayHeroReturn() { bool isOpen = HeroReturnManager.Instance.IsHeroReturnOpen(); heroReturnCell.SetActive(isOpen); if (!isOpen) return; heroReturnCell.Display(); } } Main/System/OpenServerActivity/OperationTimeHepler.cs
@@ -469,9 +469,9 @@ case 10: opreationType = OperationType.HeroDebut; break; // case 11: // opreationType = OperationType.HeroBack; // break; case 11: opreationType = OperationType.HeroReturn; break; } if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) @@ -1084,5 +1084,6 @@ { TimeRush = 1, //日期型活动 - 轮回殿 HeroDebut = 2, //日期型活动 - 武将登场 HeroReturn = 3, //日期型活动 - 武将返场 max, } Main/System/Redpoint/MainRedDot.cs
@@ -155,6 +155,7 @@ public const int RedPoint_OSHeroTrain = 481; public const int RedPoint_OSBeautyMM = 482; public const int RedPoint_OSMingge = 483; public const int HeroReturnRepoint = 484; //武将返场 public void Register() { Main/System/UIBase/UIJumpManager.cs
@@ -61,10 +61,9 @@ } } } else if (config.WinName == "HeroDebutCallWin" || config.WinName == "HeroDebutSkinWin" || config.WinName == "HeroDebutCheckInWin" || config.WinName == "HeroDebutGiftWin" || //武将登场相关 else if (config.WinName == "HeroDebutCallWin" || config.WinName == "HeroDebutSkinWin" || config.WinName == "HeroDebutCheckInWin" || config.WinName == "HeroDebutGiftWin" || config.WinName == "HeroDebutShopWin") { var heroDebutAct = HeroDebutManager.Instance.GetOperationHeroAppearInfo(); @@ -96,6 +95,40 @@ UIManager.Instance.OpenWindow(config.WinName); } } //武将返场相关 else if (config.WinName == "HeroReturnCallWin" || config.WinName == "HeroReturnSkinWin" || config.WinName == "HeroReturnCheckInWin" || config.WinName == "HeroReturnGiftWin" || config.WinName == "HeroReturnShopWin") { var heroDebutAct = HeroReturnManager.Instance.GetOperationHeroAppearInfo(); if (heroDebutAct == null) { SysNotifyMgr.Instance.ShowTip("ActivityNoOpen"); return; } var actHeroAppearConfig = ActHeroAppearConfig.Get(heroDebutAct.CfgID); if (actHeroAppearConfig == null) { SysNotifyMgr.Instance.ShowTip("ActivityNoOpen"); return; } // 皮肤商店需要判断物品ID if (config.WinName == "HeroReturnSkinWin") { if (!HeroReturnManager.Instance.HasItemInSkinCTGIDList(heroDebutAct.CfgID, int.Parse(config.Extra))) { SysNotifyMgr.Instance.ShowTip("ActivityNoOpen"); return; } } if (UIManager.Instance.IsOpened(config.WinName)) { UIManager.Instance.CloseWindow(config.WinName); UIManager.Instance.OpenWindow(config.WinName); } } if (!UIManager.Instance.IsOpened(config.WinName)) { Main/Utility/EnumHelper.cs
@@ -858,6 +858,7 @@ OSMingge = 61, //开服命格培养榜活动 Qunying = 62, //群英榜 HeroDebut = 63,//武将登场 HeroReturn = 64, //武将返场 } @@ -1813,6 +1814,7 @@ { TimeRushAct = 200, //轮回殿(武将冲刺) HeroDebutAct = 201, //英雄登场活动 HeroReturnAct = 202, //英雄返场活动 } //仙玉购买的二次确认框类型