using Assets.Framework.Tool; using Assets.MyGame.Scripts.Net; using Assets.MyGame.Scripts.Net.API; using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass; using Assets.MyGame.Scripts.Net.APIResponses.Enum; using DG.Tweening; using Spine.Unity; using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; /// /// 星际迷航(XJMH)主面板:只放 XJMH 专属逻辑(炮台切换面板、金币柱、核弹道具)。 /// 通用逻辑都在父类 GameMainPanel_FishBase(三个游戏共用,不动具体实现)。 /// XJMH 专属表现移植自原版 Lua: /// 切换面板 ← PW_SelectBatteryView(EnterAction / ExitAction / UpdateBattery / SelectBattery) /// 金币柱 ← PW_GoldColumnMgr / PW_GoldColumn(见 GoldColumnController) /// 道具 ← 原版只开放核弹头:按钮 + 缩放面板(面板同"道具二层"样式,条目按后端核弹数据自动生成) /// 设置 ← 按钮 + 缩放面板(覆写父类的宽度展开动画,只影响 XJMH) /// public class GameMainPanel_XJMH : GameMainPanel_FishBase { // ==================== 炮台切换面板(按钮式) ==================== [Header("炮台切换面板")] [Tooltip("长按 img_OpenPT 弹出的切换面板(预制体里嵌的是原版 PW_SelectBatteryView 界面)")] public GameObject ChangePTPanel; public Button btn_GreenPT; // 对应 xjmhTurretList[0] public Button btn_BluePT; // 对应 xjmhTurretList[1] public Button btn_GoldPT; // 对应 xjmhTurretList[2] public Button btn_VIPPT; // 对应 xjmhTurretList[3] // 按钮与列表索引的映射(顺序固定:Green=0, Blue=1, Gold=2, VIP=3) private Button[] _ptButtons; [Header("炮台解锁限制(索引=按钮顺序 0绿/1蓝/2金/3VIP;非VIP只能用第一个)")] [Tooltip("每个炮台所需贵族(VIP)等级,0=不限制。当前规则:只要是 VIP(≥1),后面三个都能用")] public int[] ptUnlockVipLevel = { 0, 1, 1, 1 }; [Tooltip("每个炮台是否额外要求月卡在有效期内(当前规则不启用月卡限制,需要时把第 4 个勾上)")] public bool[] ptUnlockNeedMonthCard = { false, false, false, false }; [Tooltip("贵族等级不足时按钮 LimitTip 的提示文案,{0}=所需贵族等级(原版 LevelLimit)")] public string ptLockTipVipFormat = "贵族{0}解锁"; [Tooltip("需要月卡时按钮 LimitTip 的提示文案(原版 MemberBattery2)")] public string ptLockTipMonthCard = "月卡专属"; [Tooltip("未解锁炮台按钮上的遮挡灰幕颜色(半透明灰)")] public Color ptLockMaskColor = new Color(0f, 0f, 0f, 0.55f); // 每个按钮的未解锁灰幕(懒创建后缓存复用;面板销毁时随之销毁) private readonly Dictionary _ptLockMasks = new Dictionary(); // ⭐ 原版 PW_SelectBatteryView 的三个滑动节点(预制体里就是原版界面结构): // mGOContent(内容)从下方滑入滑出;mBtnUserInfo(头像)/ mGOGirl(看板娘)从左侧滑入滑出 private RectTransform _ptContent; private RectTransform _ptUserInfo; private RectTransform _ptGirl; private Vector2 _ptContentHome; private Vector2 _ptUserInfoHome; private Vector2 _ptGirlHome; [Header("切换面板动画(原版 EnterAction/ExitAction 参数,可在面板上实时调)")] [Tooltip("内容/头像/看板娘的滑动距离(像素),原版 500")] public float ptSlideDistance = 500f; [Tooltip("滑入/滑出时长(秒),原版 0.3")] public float ptSlideTime = 0.3f; // ==================== 金币柱 ==================== [Tooltip("金币柱控制器:可在预制体上手动挂 GoldColumnController 并拖进来(参数可存盘、Inspector 实时可调);留空则运行时自动挂")] public GoldColumnController goldColumnController; private GoldColumnController _goldColumn; [Header("金币柱位置(面板上实时调,每次出柱生效;左右座位各一套)")] [Tooltip("左座位:首柱相对座位的 X 偏移(以此处为准,控制器组件上的同名字段会被覆盖)")] public float goldColumnOffsetX = 150f; [Tooltip("左座位:相邻金币柱的 X 间距")] public float goldColumnDeltaX = 40f; [Tooltip("左座位:金币柱 Y(相对面板底边,0=贴着底边往上长)")] public float goldColumnOffsetY = 0f; [Tooltip("右座位:首柱相对座位的 X 偏移(左/右按座位在面板中线的左/右判定)")] public float goldColumnOffsetXRight = 150f; [Tooltip("右座位:相邻金币柱的 X 间距")] public float goldColumnDeltaXRight = 40f; [Tooltip("右座位:金币柱 Y(相对面板底边,0=贴着底边往上长)")] public float goldColumnOffsetYRight = 0f; // ==================== 核弹列表(按钮 + 缩放面板) ==================== [Header("核弹列表(按钮 + 缩放面板)")] [Tooltip("打开核弹列表的按钮(原版道具入口,与通用道具按钮 btn_Prop 分离);拖你要用的那个按钮本身即可。留空则核弹列表没有入口")] public Button btn_NukeList; [Tooltip("核弹列表面板:点按钮后缩放弹出,条目自动生成在它下面(做成道具二层同款:Image + HorizontalLayoutGroup + ContentSizeFitter)")] public GameObject nukeListPanel; [Tooltip("核弹条目模板:不拖则用父类道具二层的模板 tmp_PropTwoItem")] public GameObject nukeItemTemplate; // ==================== 设置列表(按钮 + 缩放面板) ==================== [Header("设置列表(按钮 + 缩放面板)")] [Tooltip("打开设置列表的按钮;留空则沿用父类 btn_SettingList(两个按钮都可用)")] public Button btn_SettingPopup; [Tooltip("设置列表备用面板(一般不用拖:默认用父类的 SittingListParent 通用设置列表;仅当 SittingListParent 没挂时才用这个)")] public GameObject settingListPanel; // ==================== 帮助面板(原版 PW_Help:图鉴 / 操作 / 玩法) ==================== [Header("帮助面板(原版 PW_Help:图鉴/操作/玩法)")] [Tooltip("打开帮助面板的按钮(如设置列表里的帮助项);留空则该面板没有入口")] public Button btn_HelpPopup; [Tooltip("帮助面板:拖 XJMH 预制体里已嵌好的 PW_Help 物体(初始会自动隐藏)")] public GameObject helpPanel; [Tooltip("图鉴条目模板:拖当前图鉴的 TuJianItem 条目;留空则图鉴页签只切换、不生成条目")] public TuJianItem helpTuJianItemTemplate; [Tooltip("操作/玩法条目模板:拖 Assets/Art/XJMH/pw/pw_prefab/item/PW_HelpItem2.prefab(内含 _textName / _textDes1~11 / _imgIcon1~5);留空则这两个页签只切换、不生成条目")] public GameObject helpItem2Template; // ==================== 锁定设置面板(长按锁定键打开,原版 PW_SetLock) ==================== [Header("锁定设置面板(长按锁定键打开,原版 PW_SetLock)")] [Tooltip("原版 PW_SetLock 面板:拖 Assets/Art/XJMH/pw/pw_prefab/msgbox/PW_SetLock.prefab 的实例(初始自动隐藏);留空则长按锁定退回通用 SuoDing 面板")] public GameObject lockSetPanel; [Tooltip("锁定条目模板:拖 Assets/Art/XJMH/pw/pw_prefab/item/PW_SetLockItem.prefab;留空则只开关面板、不生成条目")] public GameObject lockSetItemTemplate; // ==================== 设置面板(原版 PW_Set:音乐/音效/震动 + 画质三档) ==================== [Header("设置面板(原版 PW_Set:音乐/音效/震动 + 画质)")] [Tooltip("打开设置面板的按钮(如设置列表里的设置项);留空则该面板没有入口")] public Button btn_SetPopup; [Tooltip("设置面板:拖 XJMH 预制体里已嵌好的 PW_Set 物体(初始会自动隐藏)。\n开关与通用设置(UIHome_BY_SettingPenel)同一套存储:音乐/音效=slider 0/1、画质=GraphicsQuality")] public GameObject setPanel; // ==================== 退出倒计时(原版 PW_ExitView) ==================== [Header("退出倒计时(原版 PW_ExitView)")] [Tooltip("原版 PW_ExitView 面板:拖 Assets/Art/XJMH/pw/pw_prefab/view/PW_ExitView.prefab 的实例(初始自动隐藏);留空则点退出走父类确认框流程")] public GameObject exitViewPanel; [Tooltip("倒计时起始秒数(原版 3:显示 3→2→1→0 后进入退出加载界面)")] public int exitViewSeconds = 3; [Tooltip("数字跳动放大倍数(原版 1.6)")] public float exitBounceScale = 1.6f; [Tooltip("跳动放大时长(秒,原版 0.05)")] public float exitBounceUpTime = 0.05f; [Tooltip("跳动回弹时长(秒,原版 0.3)")] public float exitBounceBackTime = 0.3f; [Tooltip("每拍跳动音效 id(PW_Button,原版 SoundMgr:PlaySound(Button))")] public int exitBounceAudioID = 60009; [Tooltip("副标题文案(原版 PW_Config.Text.SyncServerData)")] public string exitViewTipText = "同步服务器数据中..."; // ==================== 断线重连等待提示(Hl_WaitTip) ==================== [Header("断线重连等待提示(Hl_WaitTip)")] [Tooltip("Hl_WaitTip 面板:拖 Assets/hall/hallprefab/view/Hl_WaitTip.prefab 的实例(建议放进面板预制体最上层;自带全屏 Canvas + 转圈粒子,初始自动隐藏);留空则不提示")] public GameObject waitTipPanel; [Tooltip("提示文案(预制体默认「正在连接服务器...」)")] public string waitTipMessage = "正在连接服务器..."; // ==================== 免费模式框(原版 PW_Battery_FreeFrame_L/R) ==================== [Header("免费模式框(原版 PW_Battery_FreeFrame_L/R)")] [Tooltip("左侧免费模式框:拖 Assets/Art/XJMH/pw/pw_prefab/game/battery/PW_Battery_FreeFrame_L.prefab 的实例(建议摆在左侧座位炮台下方,初始自动隐藏)")] public GameObject freeFrameL; [Tooltip("右侧免费模式框:拖 PW_Battery_FreeFrame_R.prefab 实例(建议摆在右侧座位炮台下方)")] public GameObject freeFrameR; [Tooltip("自己进入免费模式时的滑入距离(像素,原版 200)")] public float freeFrameSlideDistance = 200f; [Tooltip("滑入时长(秒,原版 0.4)")] public float freeFrameSlideInTime = 0.4f; [Tooltip("滑出时长(秒,原版 0.3)")] public float freeFrameSlideOutTime = 0.3f; [Tooltip("触发免费模式的鱼号列表(默认 12025 弹药箱):击杀后按配置里该鱼的 times 秒显示免费框;\n需要其它鱼(女龙王等)往这里加鱼号即可")] public List freeModeFishNumbers = new List { "12025" }; [Tooltip("配置里查不到 times 时的兜底时长(秒)")] public float freeModeFallbackSeconds = 10f; [Tooltip("免费模式框总开关:关闭时功能停用(不响应击杀广播、不显示);面板勾上即可恢复")] public bool freeFrameEnabled = false; [Header("核弹列表动画(照原版 Rocket 逐项弹出)")] [Tooltip("相邻条目的弹出/收缩间隔(秒),原版 0.1")] public float nukeItemStagger = 0.1f; [Tooltip("单个条目单步缩放时长(秒),原版 0.1;展开共 4 步:0→1→压扁→拉长→回正")] public float nukeItemPopTime = 0.1f; [Header("设置弹窗缩放时长(照原版 BoxBase)")] [Tooltip("设置面板展开时长(秒),原版 0.3")] public float popupOpenTime = 0.3f; [Tooltip("设置面板收起时长(秒),原版 0.3")] public float popupCloseTime = 0.3f; public override void Awake() { base.Awake(); InitPTPanel(); InitNukeProp(); InitSettingPopup(); InitHelpPanel(); InitLockSetPanel(); InitSetPanel(); InitExitView(); InitWaitTip(); InitFreeFrame(); } public override void Start() { base.Start(); // ⭐ 关掉锁定开关 → 退出"锁定面板锁定"模式(与父类通用版语义一致): // 下次再开锁定开关 = 正常锁定,不受锁定面板勾选约束 if (toggle_Lock != null) { toggle_Lock.onValueChanged.AddListener(on => { if (!on) _xjLockWhiteOn = false; }); } } protected override void OnShow(object args = null) { base.OnShow(args); AudioManager.Instance.ChangeBG(61109); } /// 玩法 BGM(加载完成确认点会再置一次,防止被大厅面板 Hide 覆盖) protected override int GameBgmAudioId => 61109; // ==================== 切换面板:初始化 / 显示 / 隐藏 ==================== /// 初始化切换面板:绑定按钮点击、抓原版滑动节点、默认隐藏 private void InitPTPanel() { _ptButtons = new Button[] { btn_GreenPT, btn_BluePT, btn_GoldPT, btn_VIPPT }; for (int i = 0; i < _ptButtons.Length; i++) { int idx = i; // 闭包捕获 if (_ptButtons[i] != null) _ptButtons[i].onClick.AddListener(() => OnPTButtonClicked(idx)); } if (ChangePTPanel == null) return; // 原版 PW_SelectBatteryView 的滑动节点 + 原位(进出场动画用) _ptContent = FindChildByName(ChangePTPanel.transform, "mGOContent") as RectTransform; _ptUserInfo = FindChildByName(ChangePTPanel.transform, "mBtnUserInfo") as RectTransform; _ptGirl = FindChildByName(ChangePTPanel.transform, "mGOGirl") as RectTransform; if (_ptContent != null) _ptContentHome = _ptContent.anchoredPosition; if (_ptUserInfo != null) _ptUserInfoHome = _ptUserInfo.anchoredPosition; if (_ptGirl != null) _ptGirlHome = _ptGirl.anchoredPosition; // ⭐ 原版整屏根节点自带"点空白关闭"按钮(新版预制体里接的是 SetActive(false) 硬关), // 这里改接原版 ExitAction 的滑动收场,关得和原版一样 var bgBtn = ChangePTPanel.GetComponent