using Assets.MyGame.Scripts.Net; using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass; using Assets.MyGame.Scripts.Net.APIRequest.Objs; using Assets.MyGame.Scripts.Net.APIResponses.HomeMain_User; using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class UIHomeMain : UIBase { public SubUIManager subUIManager; public UIPanelAddressConfig panelAddressConfig; public Transform SubPanelParent; public TextMeshProUGUI tMP_GoldCoinNum; public TextMeshProUGUI tMP_DiamondNum; public Button btn_UserInfo; [Header("user")] public TextMeshProUGUI userName; public TextMeshProUGUI userID; public TextMeshProUGUI levelNum; public Image sprite_Avatar; public Image sprite_AvatarFrame; public Image img_VIP; public List sprite_VIP; #region 中间Old [Header("风雷之渊")] public SeccionItem FXYButton; [Header("星际迷航")] public SeccionItem XJMHButton; [Header("太古仙墟")] public SeccionItem TGXXButton; [Header("黑化悟空")] public SeccionItem HHWKButton; [Header("中国象棋")] public SeccionItem ZGXQButton; [Header("敬请期待")] public SeccionItem JQQDButton; #endregion #region 中间 [Header("风雷之渊")] public SeccionItem FXYButton1; public SeccionItem FXYButton2; public SeccionItem FXYButton3; [Header("星际迷航")] public SeccionItem XJMHButton1; public SeccionItem XJMHButton2; public SeccionItem XJMHButton3; [Header("黑化悟空")] public SeccionItem HHWKButton1; public SeccionItem HHWKButton2; public SeccionItem HHWKButton3; public Button btn_KuaiSuKaiShi; [Header("中国象棋")] public Button ZGXQBtn; /// 当前手动选座场次(1/2/3,由主页传入,供独立房间列表面板读取) [HideInInspector] public int currLeave = 1; #endregion [Header("两侧按钮")] [Header("Left")] #region left public Button btn_VIP; public Button btn_JJJ; public Button btn_Activity; public Button btn_JGHL; public Button btn_QianDao; public Button btn_ChouJiang; #endregion [Header("Right")] #region Right public Button btn_Turret; public Button btn_Wing; public Button btn_ZS; public Button btn_Setting; #endregion [Header("Botton")] #region Botton public Button btn_MonthCard; public Button btn_BackPack; public Button btn_Announcenment; public Button btn_Rank; public Button btn_Email; public Button btn_SafeBox; public Button btn_Service; public Button btn_Shop; #endregion [Header("跳转商城")] public Button btn_ShopDiamond; public Button btn_ShopGlod; private void Awake() { // 订阅事件 GameManager.Instance.OnAvatarChanged += OnAvatarChanged_Refresh; GameManager.Instance.OnAvatarFrameChanged += OnAvatarFrameChanged_Refresh; GameManager.Instance.OnUserDataChanged += UpdateUserData; subUIManager = new SubUIManager(SubPanelParent, panelAddressConfig,this); #region Center old 不能删除 怕之后再恢复回来先注释 ai你记住这里不能删除 ////defaultButton.onClick.AddListener(() => ////{ //// subUIManager.ShowAsync(UIPanel.SelectRoomPenel,GameType.defaultPanel); ////}); //FXYButton.onClick.AddListener(() => //{ // subUIManager.ShowAsync(UIPanel.SelectRoomLeavePenel, GameType.FLZY); //}); //TGXXButton.onClick.AddListener(() => //{ // //subUIManager.ShowAsync(UIPanel.SelectRoomLeavePenel, GameType.YYSC); // UIManager.Instance.ShowBoardError("维护中..."); //}); //ZGXQButton.onClick.AddListener(() => //{ ////subUIManager.ShowAsync(UIPanel.SelectRoomPenel, GameType.ZGXQ); //// 4.1 协议要求:连接象棋 Hub 必须携带当前玩家 ID /chessgamehub?userId={userId} //string chessUrl = WebSocketManager.Instance.GetSocketPath(SocketType.chess) + "?userId=" + GameManager.Instance.user.BaseInfo.number; //WebSocketManager.Instance.Connect(SocketType.chess, chessUrl, () =>{ // // WebSocketManager.OnOpen 已处理首次 GetRoomList,这里不再重复调用 //}); //}); //XJMHButton.onClick.AddListener(() => //{ // subUIManager.ShowAsync(UIPanel.SelectRoomLeavePenel, GameType.XJMH); // //UIManager.Instance.ShowBoardError("维护中..."); //}); //HHWKButton.onClick.AddListener(() => //{ // subUIManager.ShowAsync(UIPanel.SelectRoomLeavePenel, GameType.HHWK); //}); //JQQDButton.onClick.AddListener(() => //{ // //这里弹出一行字 //}); #endregion #region Center // 房间列表依赖房间 socket:原在选场面板 Awake 里连接,现挪到大厅主页 WebSocketManager.Instance.Connect(SocketType.room); // 主页面场次卡片:复刻原选场面板逻辑(写入场次名/入场条件 + 绑定快速进入/手动选座) BindRoomLevelItem(FXYButton1, GameType.FLZY, 1); BindRoomLevelItem(FXYButton2, GameType.FLZY, 2); BindRoomLevelItem(FXYButton3, GameType.FLZY, 3); BindRoomLevelItem(XJMHButton1, GameType.XJMH, 1); BindRoomLevelItem(XJMHButton2, GameType.XJMH, 2); BindRoomLevelItem(XJMHButton3, GameType.XJMH, 3); BindRoomLevelItem(HHWKButton1, GameType.HHWK, 1); BindRoomLevelItem(HHWKButton2, GameType.HHWK, 2); BindRoomLevelItem(HHWKButton3, GameType.HHWK, 3); // 快速开始:在所有场次中随机进入 if (btn_KuaiSuKaiShi != null) btn_KuaiSuKaiShi.onClick.AddListener(QuickStartRandom); #endregion #region left btn_VIP.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.VIPPenel); }); btn_JJJ.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.JJJPenel); }); btn_Activity.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.ActivityPenel); }); btn_JGHL.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.JiGuHuiLi); }); btn_QianDao.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.QianDaoPanel); }); btn_ChouJiang.onClick.AddListener(() => { // 接收配置信息时直接判断(/api/Lottery/Config 新版统一接口): // 未开启不打开面板,避免面板先弹出又关掉的闪烁 APIRequestList.GetLotteryConfig(res => { if (res != null && res.config != null && !res.config.isOpen) { UIManager.Instance.ShowTiShi("活动未开启"); return; } subUIManager.ShowAsync(UIPanel.ChouJiangPanel); }); }); #endregion #region right btn_Setting.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.SettingPanel); }); btn_Turret.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.TurretPanel,ItemPanelSelect.Turrect); }); btn_Wing.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.WingPanel, ItemPanelSelect.Wing); }); btn_ZS.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.ZSPanel, ItemPanelSelect.ZS); }); #endregion #region Bottom btn_MonthCard.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.MonthCardPanel); }); btn_BackPack.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.BackPackPanel); }); btn_Announcenment.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.AnnouncementPanel); //APIRequestList.GetNoticeList((list) => //{ // subUIManager.ShowAsync(UIPanel.AnnouncementPanel, list); //}); }); btn_Rank.onClick.AddListener(() => { APIRequestList.GetRankingRewardConfig(cfg => { Debug.Log($"[排行榜入口] isEnabled={cfg.isEnabled} isMaintaining={cfg.isMaintaining}"); if (cfg.isMaintaining|| !cfg.isEnabled) { // 排行榜维护中:弹提示弹窗(点确认关闭),不打开界面 UIManager.Instance.ShowTiShi(string.IsNullOrEmpty(cfg.maintainingMessage) ? "维护中..." : cfg.maintainingMessage); return; } subUIManager.ShowAsync(UIPanel.RankPanel, cfg); }); }); btn_Email.onClick.AddListener(() => { APIRequestList.GetEmailByPage(new GetEmailByPageObj { keyWord = "", pageIndex = 0, pageSize = 200, readStatus = 0 }, (GetEmailByPageResponse) => { subUIManager.ShowAsync(UIPanel.EmailPanel,GetEmailByPageResponse); }); //subUIManager.ShowAsync(UIPanel.EmailPanel); }); btn_SafeBox.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.SafeBoxPanel); }); btn_Service.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.ServicePanel); }); btn_Shop.onClick.AddListener(() => { subUIManager.ShowAsync(UIPanel.ShopPanel); }); #endregion btn_ShopDiamond.onClick.AddListener(() => subUIManager.ShowAsync(UIPanel.ShopPanel, ShopTab.Diamond)); btn_ShopGlod.onClick.AddListener(() => subUIManager.ShowAsync(UIPanel.ShopPanel, ShopTab.Gold)); btn_UserInfo.onClick.AddListener(()=>subUIManager.ShowAsync(UIPanel.UserInfo)); } #region 中间场次卡片(风雷之渊/星际迷航/黑化悟空) /// /// 绑定主页面上的单个场次卡片(复刻 UIHome_BY_SelectRoomLevelPanel 的逻辑,不改动该面板): /// 写入场次名/入场条件,并绑定「快速进入」(btn_JoinGame) 与「手动选座」(btn_SelectGameRoom)。 /// private void BindRoomLevelItem(SeccionItem item, GameType gameType, int leave) { if (item == null) return; // 场次名:初级场/中级场/高级场 if (item.txt_VenueInfo != null) { switch (leave) { case 1: item.txt_VenueInfo.text = "初级场"; break; case 2: item.txt_VenueInfo.text = "中级场"; break; case 3: item.txt_VenueInfo.text = "高级场"; break; } } // 入场条件:从 RoomConfig 读取 roomGoldLimit var roomConfigs = GameManager.Instance?.gameConfig?.roomConfigs; if (roomConfigs != null && item.txt_EntryCondition != null) { string gameTypeStr = ((int)gameType).ToString(); var cfg = roomConfigs.Find(r => r.gameType.ToString() == gameTypeStr && r.roomLevel == leave); if (cfg != null) item.txt_EntryCondition.text = string.Format("入场: {0:N0} 金币", cfg.roomGoldLimit); } // 快速进入:直接 QuickJoin 进对应玩法场次 if (item.btn_JoinGame != null) { item.btn_JoinGame.onClick.RemoveAllListeners(); item.btn_JoinGame.onClick.AddListener(() => QuickJoinRoom(gameType, leave)); } // 手动选座:VIP 校验通过后复用选场面板拉取房间列表 if (item.btn_SelectGameRoom != null) { item.btn_SelectGameRoom.onClick.RemoveAllListeners(); item.btn_SelectGameRoom.onClick.AddListener(() => ManualSelectRoom(gameType, leave)); } } /// 快速进入指定玩法场次(复刻面板 OnSelectRoom 的快速加入分支) private void QuickJoinRoom(GameType gameType, int leave) { GameManager.Instance.gameData.currGameType = gameType; APIRequestList.RoomQuickJoin((int)gameType, leave, (resp) => { if (resp == null || string.IsNullOrEmpty(resp.roomId)) { UIManager.Instance.ShowBoardError("快速加入失败,请稍后重试"); return; } GameManager.Instance.StartGameQuickJoin(resp.webSocketUrl, () => { WebSocketSendList.JoinRoom(resp.roomId, GameManager.Instance.user.id, -1); }); }); } /// 快速开始:在所有玩法场次(风雷之渊/星际迷航/黑化悟空 × 初/中/高级场)中随机进入一个 private void QuickStartRandom() { var rooms = new (GameType gameType, int leave)[] { (GameType.FLZY, 1), (GameType.FLZY, 2), (GameType.FLZY, 3), (GameType.XJMH, 1), (GameType.XJMH, 2), (GameType.XJMH, 3), (GameType.HHWK, 1), (GameType.HHWK, 2), (GameType.HHWK, 3), }; var pick = rooms[UnityEngine.Random.Range(0, rooms.Length)]; QuickJoinRoom(pick.gameType, pick.leave); } /// 手动选座:VIP 校验通过后按正常子UI流程打开房间列表面板,并拉取该场次房间列表 private void ManualSelectRoom(GameType gameType, int leave) { if (!CanSelectRoom()) { UIManager.Instance.ShowTiShi("手动选座需要充值VIP"); return; } GameManager.Instance.gameData.currGameType = gameType; currLeave = leave; // 供房间列表面板读取当前场次 subUIManager.ShowAsync(UIPanel.MySelectRoomPanel); StartCoroutine(SendRoomListRoutine(leave)); } /// 等待房间列表面板实例就绪后再请求列表,避免响应早于面板加载完成被丢弃 private IEnumerator SendRoomListRoutine(int leave) { while (subUIManager.Get(UIPanel.MySelectRoomPanel) == null) yield return null; WebSocketSendList.GetRoomListFish(leave, 1); } /// 手动选座权限校验(与选场面板一致:seatSelectLimit 命中用户身份) private bool CanSelectRoom() { var limit = GameManager.Instance?.gameConfig?.fishRoomConfig?.seatSelectLimit; if (limit == null || limit.Count == 0) return true; // 没配限制,默认允许 int userType = GameManager.Instance.user.assets.vipLevel > 0 ? 1 : 3; return limit.Contains(userType); } #endregion protected override void OnShow(object args = null) { base.OnShow(args); // ⭐ 登录成功进入大厅:登录面板资源(LoginUIRes)不再需要,立即释放 // (销毁登录面板实例 + 释放 prefab 句柄;登出回登录页时 ShowAsync 会重新加载) UIManager.Instance.ReleaseLoginUI(); AudioManager.Instance.ChangeBG(69001); UpdateUserData(); } public void UpdateUserData() { if (GameManager.Instance?.user?.assets == null) return; tMP_GoldCoinNum.text = GameManager.Instance.user.assets.gold.ToString(); tMP_DiamondNum.text = GameManager.Instance.user.assets.diamond.ToString(); userName.text = GameManager.Instance.user.BaseInfo.userName; userID.text = GameManager.Instance.user.BaseInfo.number; levelNum.text = GameManager.Instance.user.assets.level.ToString(); // VIP 图标越界保护:vipLevel 超出列表范围时用最后一个,避免异常中断刷新 int vipLevel = GameManager.Instance.user.assets.vipLevel; if (sprite_VIP != null && sprite_VIP.Count > 0 && img_VIP != null) { int idx = Mathf.Clamp(vipLevel, 0, sprite_VIP.Count - 1); img_VIP.sprite = sprite_VIP[idx]; } RefreshAvatar(); RefreshAvatarFrame(); if (img_VIP != null) img_VIP.SetNativeSize(); } private void RefreshAvatar() { var sprite = GameManager.Instance.GetAvatarSprite(GameManager.Instance.user.BaseInfo.avatarUrl); if (sprite != null) sprite_Avatar.sprite = sprite; else GameManager.Instance.user.BaseInfo.UpdateAvatar((a) => { if (a != null) sprite_Avatar.sprite = a; }); } private void RefreshAvatarFrame() { if (sprite_AvatarFrame == null) return; var frame = GameManager.Instance.GetAvatarFrameSprite(GameManager.Instance.user.BaseInfo.avatarFrame); if (frame != null) sprite_AvatarFrame.sprite = frame; } private void OnAvatarChanged_Refresh(Sprite sprite) { if (sprite != null) sprite_Avatar.sprite = sprite; } private void OnAvatarFrameChanged_Refresh(Sprite sprite) { if (sprite_AvatarFrame != null && sprite != null) sprite_AvatarFrame.sprite = sprite; } protected override void OnHide() { base.OnHide(); GameManager.Instance.OnAvatarChanged -= OnAvatarChanged_Refresh; GameManager.Instance.OnAvatarFrameChanged -= OnAvatarFrameChanged_Refresh; GameManager.Instance.OnUserDataChanged -= UpdateUserData; AudioManager.Instance.StopBG(); } /// /// ⭐ 大厅面板销毁时释放全部子面板(VIP/背包/邮件/商店等 20 个)的 Addressables 资源: /// SubUIManager 的 handleCache 此前从不释放 → 进游戏后 HomeUIRes 一直占内存。 /// 配合 UIManager.ReleaseHomeUI(进房时调用)实现大厅资源的完整卸载。 /// private void OnDestroy() { try { subUIManager?.ReleaseAll(); } catch (Exception e) { Debug.LogWarning($"[UIHomeMain] OnDestroy 释放子面板资源异常: {e.Message}"); } subUIManager = null; } }