From d3d160518b1656f4783e80bbba42e40e4455ce86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A3=AE2003?= <2384017988@qq.com> Date: Sun, 4 Oct 2026 18:59:57 +0800 Subject: [PATCH] 1 --- .../aa/UI/Game/GameMainPanel_FishBase.cs | 16 +- .../aa/UI/Game/XJMH/GameMainPanelXJMH.prefab | 153 ++++++++ .../aa/UI/Game/XJMH/GameMainPanel_XJMH.cs | 363 +++++++++++++++++- 3 files changed, 525 insertions(+), 7 deletions(-) diff --git a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs index 7428a6509..33e050685 100644 --- a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs +++ b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs @@ -969,6 +969,16 @@ public class GameMainPanel_FishBase : GameMainPanel_Base RestoreFrozenDirectors(); } + + /// + /// ⭐ 长按锁定键(0.6秒)打开的"锁定设置"面板。 + /// 默认 = 通用 SuoDing 面板;XJMH 覆写为原版 PW_SetLock 面板(其白名单通过覆写 IsFishAllowedBySuoDing 提供)。 + /// + protected virtual void OpenLockSettingPanel() + { + subUIManager.ShowAsync(UIPanel.GameSuoDing); + } + public virtual void Start() { btn_SettingList.onClick.AddListener(() => @@ -1013,9 +1023,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base if (lockLongPress == null) lockLongPress = toggle_Lock.gameObject.AddComponent(); lockLongPress.onLongPress += () => { - subUIManager.ShowAsync(UIPanel.GameSuoDing); + OpenLockSettingPanel(); }; } + toggle_BaoZou.onValueChanged.AddListener(on => { if (!on) @@ -3804,8 +3815,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base /// - 非"图鉴锁定"模式 → 不限制(正常锁定想锁什么就锁什么) /// - 图鉴锁定模式:一个都没勾 → 不限制;勾了至少一条 → 只允许锁勾选的鱼 /// 手动锁定(玩家点击选鱼)不受此限制。 + /// ⭐ XJMH 覆写本方法改用原版 PW_SetLock 面板的勾选列表。 /// - private bool IsFishAllowedBySuoDing(MonsterContral m) + protected virtual bool IsFishAllowedBySuoDing(MonsterContral m) { // ⭐ 只有走"长按图鉴"那条路才启用白名单,避免图鉴勾选干扰正常锁定 if (!_suoDingMode) return true; diff --git a/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanelXJMH.prefab b/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanelXJMH.prefab index f919aba7f..5572e866f 100644 --- a/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanelXJMH.prefab +++ b/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanelXJMH.prefab @@ -4149,6 +4149,7 @@ RectTransform: - {fileID: 6208906429163189928} - {fileID: 8927348487773343547} - {fileID: 1425888953497163554} + - {fileID: 6781559484914116352} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -4280,6 +4281,9 @@ MonoBehaviour: type: 3} helpItem2Template: {fileID: 1945686605193428, guid: 4a2156dc91c438048ae799db55c7113d, type: 3} + lockSetPanel: {fileID: 6702752155659137683} + lockSetItemTemplate: {fileID: 1136181874444908, guid: 53ed3608912462847bc3c8795cdbdb50, + type: 3} nukeItemStagger: 0.1 nukeItemPopTime: 0.1 popupOpenTime: 0.2 @@ -17761,6 +17765,155 @@ RectTransform: type: 3} m_PrefabInstance: {fileID: 6189131244199501401} m_PrefabAsset: {fileID: 0} +--- !u!1001 &6702469639535777356 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 245637205031072731} + m_Modifications: + - target: {fileID: 1971641677849823, guid: 664565cc384b89c41ac1e44c5ece078a, type: 3} + propertyPath: m_Name + value: PW_SetLock + objectReference: {fileID: 0} + - target: {fileID: 224268524126657739, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_SizeDelta.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224268524126657739, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_SizeDelta.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224442425200591311, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_SizeDelta.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224442425200591311, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_SizeDelta.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_AnchorMax.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_AnchorMax.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_AnchorMin.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_AnchorMin.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_SizeDelta.x + value: 969 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_SizeDelta.y + value: 593 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_AnchoredPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_AnchoredPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: -0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 664565cc384b89c41ac1e44c5ece078a, type: 3} +--- !u!1 &6702752155659137683 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 1971641677849823, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + m_PrefabInstance: {fileID: 6702469639535777356} + m_PrefabAsset: {fileID: 0} +--- !u!224 &6781559484914116352 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a, + type: 3} + m_PrefabInstance: {fileID: 6702469639535777356} + m_PrefabAsset: {fileID: 0} --- !u!1001 &6807194459827413149 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanel_XJMH.cs b/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanel_XJMH.cs index 03374950a..0c5393ef7 100644 --- a/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanel_XJMH.cs +++ b/Assets/MyGame/aa/UI/Game/XJMH/GameMainPanel_XJMH.cs @@ -94,6 +94,14 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase [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; + + [Header("核弹列表动画(照原版 Rocket 逐项弹出)")] [Tooltip("相邻条目的弹出/收缩间隔(秒),原版 0.1")] public float nukeItemStagger = 0.1f; @@ -113,11 +121,22 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase InitNukeProp(); InitSettingPopup(); InitHelpPanel(); + InitLockSetPanel(); } 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) @@ -212,6 +231,14 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase helpPanel.transform.localScale = Vector3.one; helpPanel.SetActive(false); } + + // 锁定设置面板:离场立即收起 + if (lockSetPanel != null) + { + lockSetPanel.transform.DOKill(); + lockSetPanel.transform.localScale = Vector3.one; + lockSetPanel.SetActive(false); + } } /// @@ -1163,15 +1190,22 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase return dic.TryGetValue(fishNumber, out var sprite) ? sprite : null; } - /// - /// 设置条目里某个文本节点的位置与内容。 - /// ⭐ PW_HelpItem2.prefab 里的文本挂的是 UGUI 老版 Text(原版组件,PW_CN_Font 中文字体), - /// 不是 TMP → 两种都要兼容(TMP 优先,找不到再写老版 Text)。 - /// + /// 设置条目里某个文本节点的位置与内容(帮助/锁定条目通用:先摆位置再写文本) private static void SetHelpText(Transform tf, float x, float y, string text) { if (tf == null) return; tf.localPosition = new Vector3(x, y, 0f); + SetTextContent(tf, text); + } + + /// + /// 写文本内容(不动位置)。 + /// ⭐ 原版 pw 预制体(PW_HelpItem2 / PW_SetLockItem)里的文本挂的是 UGUI 老版 Text + /// (原版组件,PW_CN_Font 中文字体),不是 TMP → 两种都要兼容(TMP 优先,找不到再写老版 Text)。 + /// + private static void SetTextContent(Transform tf, string text) + { + if (tf == null) return; var tmp = tf.GetComponent(); if (tmp == null) tmp = tf.GetComponentInChildren(true); @@ -1573,6 +1607,325 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase }, }; + // ==================== 锁定设置面板(原版 PW_SetLock,长按锁定键打开) ==================== + // 移植自原版 PW_SetLock.txt: + // - 列表 = 原版 PW_Config.Enemy 里 canAutoLock=true 的敌人(奇数进"1"行、偶数进"2"行,两行横向排列) + // - 点条目切换勾选(_choose 标记);mBtnAll 全选 / mBtnNone 全不选(mGOAllFlag/mGONoneFlag 指示) + // - 关闭(mBtnBack)时应用:有勾选 → 开锁定 + 激活自动锁定,且之后的自动锁定只锁勾选的鱼 + // - 白名单通过覆写父类 IsFishAllowedBySuoDing 提供,父类通用流程不动 + // - 鱼图与图鉴页同源:直接取 FishResourcesData.fishResourcesSpritesDic(不需要额外注册) + + /// 锁定条目配置(对应原版 canAutoLock 敌人;编号为本项目鱼表编号) + private sealed class XjmhLockCfg + { + public string name; // 仅日志用 + public int fishNumber; + public string score; // 原版 PW_Config.Enemy[].score 原样(富文本) + } + + /// + /// 原版 PW_Config.Enemy 中 canAutoLock=true 的敌人(按原版顺序),编号映射到本项目鱼表: + /// 12031=幸运轮、12030=破坏球、12029=星际巡航、12028=机械蝎、12026=爆裂金鲨、 + /// 12034=烈焰风暴、12023=小丑扑克、12022=幸运飞碟。 + /// ⚠️ 原版还有 type=2000 女王龙,本项目鱼表还没有它,先不加;接进鱼表后在这里补一行即可。 + /// 这里加/删一行就会自动多/少一个锁定条目和勾选项(列表、全选/全不选、白名单都按这份配置走)。 + /// + private static readonly XjmhLockCfg[] XjmhLockCfgList = + { + new XjmhLockCfg { name = "幸运轮", fishNumber = 12031, score = "特殊奖励" }, + new XjmhLockCfg { name = "破坏球", fishNumber = 12030, score = "特殊奖励" }, + new XjmhLockCfg { name = "星际巡航", fishNumber = 12029, score = "特殊奖励" }, + new XjmhLockCfg { name = "机械蝎", fishNumber = 12028, score = "特殊奖励" }, + new XjmhLockCfg { name = "爆裂金鲨", fishNumber = 12026, score = "特殊奖励" }, + new XjmhLockCfg { name = "烈焰风暴", fishNumber = 12034, score = "特殊奖励" }, + new XjmhLockCfg { name = "小丑扑克", fishNumber = 12023, score = "特殊玩法" }, + new XjmhLockCfg { name = "幸运飞碟", fishNumber = 12022, score = "特殊玩法" }, + }; + + /// 原版 PW_Config.Text.SetLockDes(面板底部说明) + private const string LockSetDesText = "勾选锁定敌机, 设定锁定范围勾选敌机将会自动锁定勾选的敌机进行射击; 若不勾选, 则需手动点击敌机进行预订射击自动开启后, 点击敌机切换锁定目标"; + + /// 锁定面板内部节点(按原版 PW_SetLock 预制体名字找) + private Button _lockBtnBack; // mBtnBack(关闭并应用) + private Button _lockBtnAll; // mBtnAll(全选) + private Button _lockBtnNone; // mBtnNone(全不选) + private GameObject _lockAllFlag; // mGOAllFlag(全选指示) + private GameObject _lockNoneFlag; // mGONoneFlag(全不选指示) + private Transform _lockRow1; // ScrollView/Viewport/Content/1(横向第一行) + private Transform _lockRow2; // ScrollView/Viewport/Content/2(横向第二行) + private RectTransform _lockContent; // ScrollView/Viewport/Content(照原版按条数调宽度) + + /// 已生成条目的勾选标记(全选/全不选/单点后统一刷新用) + private sealed class LockSetItemRef + { + public string key; // fishNumber 字符串(与锁定白名单判断一致) + public GameObject choose; // _choose 标记 + } + private readonly List _lockSetItems = new List(); + + /// 勾选的锁定鱼号(对应原版 LockEnemyList,跨开关面板保留;空 = 不限制) + private readonly HashSet _xjLockSelected = new HashSet(); + + /// 是否处于"锁定面板白名单"模式(面板勾选后开启;关掉锁定开关即退出,与通用版语义一致) + private bool _xjLockWhiteOn; + + /// + /// 锁定面板初始化:抓内部节点、绑按钮(照原版 PW_SetLock:InitUI)、写固定文案。 + /// 未拖面板时全部跳过(长按退回父类通用 SuoDing 面板,玩法不受影响)。 + /// + private void InitLockSetPanel() + { + if (lockSetPanel == null) return; + + lockSetPanel.SetActive(false); // 初始收起 + + // 背景遮挡:原版打开时禁用射击(SetCanShoot(false)),本项目等价做法 = 让面板根图挡射线, + // 避免调锁定时点到后面的打鱼输入 + var rootImg = lockSetPanel.GetComponent(); + if (rootImg != null) rootImg.raycastTarget = true; + + // 返回(照原版:关闭即保存并应用勾选) + _lockBtnBack = FindButton(lockSetPanel.transform, "mBtnBack"); + if (_lockBtnBack != null) + { + _lockBtnBack.onClick.RemoveAllListeners(); + _lockBtnBack.onClick.AddListener(OnLockSetBackClicked); + } + + // 全选 / 全不选 + _lockBtnAll = FindButton(lockSetPanel.transform, "mBtnAll"); + if (_lockBtnAll != null) + { + _lockBtnAll.onClick.RemoveAllListeners(); + _lockBtnAll.onClick.AddListener(SelectAllLockItems); + } + _lockBtnNone = FindButton(lockSetPanel.transform, "mBtnNone"); + if (_lockBtnNone != null) + { + _lockBtnNone.onClick.RemoveAllListeners(); + _lockBtnNone.onClick.AddListener(SelectNoneLockItems); + } + + // 两行条目容器(ScrollView/Viewport/Content 下的 1 / 2) + var content = FindChildByName(lockSetPanel.transform, "Content"); + _lockContent = content as RectTransform; + _lockRow1 = content != null ? content.Find("1") : null; + _lockRow2 = content != null ? content.Find("2") : null; + + _lockAllFlag = FindChildByName(lockSetPanel.transform, "mGOAllFlag")?.gameObject; + _lockNoneFlag = FindChildByName(lockSetPanel.transform, "mGONoneFlag")?.gameObject; + + // 固定文案(照原版 InitView) + SetTextContent(FindChildByName(lockSetPanel.transform, "mTextDes"), LockSetDesText); + SetTextContent(_lockBtnAll != null ? FindChildByName(_lockBtnAll.transform, "Text") : null, "全选"); + SetTextContent(_lockBtnNone != null ? FindChildByName(_lockBtnNone.transform, "Text") : null, "全不选"); + } + + /// 按名字找节点上的按钮(节点上没有就往子节点找) + private static Button FindButton(Transform root, string name) + { + var tf = FindChildByName(root, name); + if (tf == null) return null; + var btn = tf.GetComponent