diff --git a/Assets/AddressableAssetsData/Windows/addressables_content_state.bin b/Assets/AddressableAssetsData/Windows/addressables_content_state.bin index cbdec3f16..4a9995741 100644 Binary files a/Assets/AddressableAssetsData/Windows/addressables_content_state.bin and b/Assets/AddressableAssetsData/Windows/addressables_content_state.bin differ diff --git a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs index b98453da0..d1ebb49fa 100644 --- a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs +++ b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs @@ -1556,7 +1556,8 @@ public class CreateFishManager : MonoSingleton // ⭐ sitPos 用击杀者座位(含人机);房主代人机击杀 Boss 时,这里传人机座位, // 否则所有客户端都会判定为房主击杀 → 房主自己看金色(错) - int posID = killerSitPos >= 0 ? killerSitPos : currGameType.currSitData.posID; + // ⭐ 座位镜像:网络帧里的 sitPos 必须是服务端座位号,显示座位转回服务端空间 + int posID = SeatMirror.ToServer(killerSitPos >= 0 ? killerSitPos : currGameType.currSitData.posID); var sgd = new SyncGameData { sitPos = posID, @@ -1588,7 +1589,8 @@ public class CreateFishManager : MonoSingleton { if (coinNum == null || coinNum.Count == 0) return; - int posID = killerSitPos >= 0 ? killerSitPos : currGameType.currSitData.posID; + // ⭐ 座位镜像:网络帧里的 sitPos 必须是服务端座位号,显示座位转回服务端空间 + int posID = SeatMirror.ToServer(killerSitPos >= 0 ? killerSitPos : currGameType.currSitData.posID); var sgd = new SyncGameData { sitPos = posID, diff --git a/Assets/MyGame/Scripts/Net/WebSocketReponseList.cs b/Assets/MyGame/Scripts/Net/WebSocketReponseList.cs index 366823ebd..262ab2bfc 100644 --- a/Assets/MyGame/Scripts/Net/WebSocketReponseList.cs +++ b/Assets/MyGame/Scripts/Net/WebSocketReponseList.cs @@ -149,7 +149,8 @@ namespace Assets.MyGame.Scripts.Net if (panel is GameMainPanel_FishBase fishPanel && notice != null) { // 如果座位被bot占用则替换 - var targetSit = fishPanel.list_Sits.Find(s => s.posID == notice.Position); + // ⭐ 座位镜像:服务端座位转显示座位再找场景座位(JoinGame 内部也做同样转换) + var targetSit = fishPanel.list_Sits.Find(s => s.posID == SeatMirror.ToDisplay(notice.Position)); if (targetSit != null && targetSit.isBot) { targetSit.isBot = false; @@ -1034,7 +1035,8 @@ namespace Assets.MyGame.Scripts.Net } if (panel == null) return; - var targetSit = panel.list_Sits.Find(s => s.posID == position); + // ⭐ 座位镜像:服务端座位转显示座位再找场景座位 + var targetSit = panel.list_Sits.Find(s => s.posID == SeatMirror.ToDisplay(position)); if (targetSit == null) return; if (showWaiting) @@ -1112,7 +1114,8 @@ namespace Assets.MyGame.Scripts.Net if (panel == null) continue; // 不在游戏中只补数据,进房流程自己会建座位 bool isBot = p.isBot || p.userId.StartsWith("bot_"); - var targetSit = panel.list_Sits.Find(s => s.posID == p.position); + // ⭐ 座位镜像:服务端座位转显示座位再找场景座位(JoinGame 内部也做同样转换) + var targetSit = panel.list_Sits.Find(s => s.posID == SeatMirror.ToDisplay(p.position)); // 真人顶掉 bot 座位时先替换(与 RoomJoinNotice 分支同逻辑) if (targetSit != null && targetSit.isBot && !isBot) { diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab index 02956197d..c1fcbc5bd 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab @@ -653,7 +653,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 810 + depthOffset: 890 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab index 135915b57..fcf589784 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab @@ -704,7 +704,7 @@ MonoBehaviour: isRotate: 1 isNot1: 1 ischild0: 1 - depthOffset: 820 + depthOffset: 880 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab index 06e52f9f9..02da040ea 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab @@ -710,7 +710,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 840 + depthOffset: 860 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab index 63e890332..b0ce28439 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab @@ -698,7 +698,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: -850 + depthOffset: 850 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab index 391a9e197..37760e52b 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab @@ -394,7 +394,7 @@ MonoBehaviour: isRotate: 1 isNot1: 1 ischild0: 1 - depthOffset: 860 + depthOffset: 840 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab index 845a6bb5d..13629f2d5 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab @@ -426,7 +426,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 870 + depthOffset: 770 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab index 5652ccba3..69fe6884e 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab @@ -908,7 +908,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 890 + depthOffset: 810 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab index 9859be358..8ead62b46 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 1 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: 1461200f483c12642a09ef755696d8c4, + type: 3} + propertyPath: m_SortingOrder + value: -99 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: 1461200f483c12642a09ef755696d8c4, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab index 668f842e2..b9d88d190 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 0 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: 6f9ba87c0c298204597a3786e912d4f3, + type: 3} + propertyPath: m_SortingOrder + value: -100 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: 6f9ba87c0c298204597a3786e912d4f3, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab index 35a05cb59..1c468f8e5 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 0 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: b153e0a4abc0c664cb98ddf7afb53870, + type: 3} + propertyPath: m_SortingOrder + value: -98 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: b153e0a4abc0c664cb98ddf7afb53870, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab index 974f0cba2..c3a20ac67 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab @@ -283,6 +283,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 0 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: d0d8725bed789824bb1b0462fde12f45, + type: 3} + propertyPath: m_SortingOrder + value: -97 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: d0d8725bed789824bb1b0462fde12f45, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1021 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1021 Variant.prefab index bb781a6b0..09120e774 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1021 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1021 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 0 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: 51618a9fa649dc84bbbb0f2b2ae34548, + type: 3} + propertyPath: m_SortingOrder + value: -96 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: 51618a9fa649dc84bbbb0f2b2ae34548, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1022 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1022 Variant.prefab index d323c8bbe..b6ffea7d3 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1022 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1022 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 0 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: ee1e72c133ca6124485715190eaa1e3a, + type: 3} + propertyPath: m_SortingOrder + value: -95 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: ee1e72c133ca6124485715190eaa1e3a, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1023 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1023 Variant.prefab index c4413abf2..307c9f196 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1023 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1023 Variant.prefab @@ -283,6 +283,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 0 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: 4760e9d2d74a347458314fcb191d6d8b, + type: 3} + propertyPath: m_SortingOrder + value: -94 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: 4760e9d2d74a347458314fcb191d6d8b, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1024 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1024 Variant.prefab index e8b8bc04a..5dd5dae8c 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1024 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1024 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 1 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: 8aca3c1d421ff8e4c87619bd4511a615, + type: 3} + propertyPath: m_SortingOrder + value: -92 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: 8aca3c1d421ff8e4c87619bd4511a615, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab index 00bb22af5..965004ca3 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 1 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: 574ac90f80e643441b595de13ffc99fe, + type: 3} + propertyPath: m_SortingOrder + value: -90 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: 574ac90f80e643441b595de13ffc99fe, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab index 2f712eabd..192bbe529 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab @@ -289,7 +289,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 1000 + depthOffset: 900 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab index fe99813ed..382dc259d 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 1 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: 10dcab870ce73d24abf17f9ea84712ad, + type: 3} + propertyPath: m_SortingOrder + value: -91 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: 10dcab870ce73d24abf17f9ea84712ad, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab index 49688168b..b8ba63e10 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab @@ -123,6 +123,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 1 objectReference: {fileID: 0} + - target: {fileID: 210099118695303065, guid: d441aa2f2c0f8524e9a494199140b726, + type: 3} + propertyPath: m_SortingOrder + value: -93 + objectReference: {fileID: 0} m_RemovedComponents: - {fileID: 114884547391421755, guid: d441aa2f2c0f8524e9a494199140b726, type: 3} m_RemovedGameObjects: diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab index 87a9ca48a..33c69b3c2 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab @@ -350,7 +350,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 830 + depthOffset: 870 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab index ba2386e8e..fb04e4524 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab @@ -506,7 +506,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 880 + depthOffset: 820 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab index e2a55b74e..1597077de 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab @@ -760,7 +760,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 900 + depthOffset: 800 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab index 900d17513..875cecb5e 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab @@ -1099,7 +1099,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 910 + depthOffset: 790 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab index b35f6fb1e..5135627ef 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab @@ -464,7 +464,7 @@ MonoBehaviour: isRotate: 1 isNot1: 0 ischild0: 1 - depthOffset: 920 + depthOffset: 780 is2DFish: 0 sortOrder2D: 0 drawMoveLine: 0 diff --git a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs index 45de1588d..a5635fe31 100644 --- a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs +++ b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs @@ -316,6 +316,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { RoomJoinNotice roomJoinNotice = v.arguments[0]; + // ⭐ 座位镜像:进房第一时间确定本地服务端座位(2/3=上方 → 全桌上下镜像,本地永远看自己在下方) + SeatMirror.Setup(roomJoinNotice.Position); // ⭐ paoBeiList 每次进入房间都重新根据当前场次+房间等级获取, // 避免再次进入同一场次的不同等级房间时沿用旧 paoBeiList(例如先高级场后低级场) { @@ -356,7 +358,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base foreach (var item in list_Sits) { - if (item.posID == roomJoinNotice.Position) + // ⭐ 座位镜像:本地玩家的显示座位 = 服务端座位转显示空间(上方座位翻转后落回下方) + if (item.posID == SeatMirror.ToDisplay(roomJoinNotice.Position)) { currSitData = item; // ⭐ 长按本地座位的 img_OpenPT 开关炮台面板(与 btn_ChangeTurret 同逻辑) @@ -389,7 +392,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base } else { - var targetSit = list_Sits.Find(s => s.posID == roomJoinNotice.Position); + var targetSit = list_Sits.Find(s => s.posID == SeatMirror.ToDisplay(roomJoinNotice.Position)); // ⭐ 优先用后端 isBot 字段判断,兼容 userId.StartsWith("bot_") bool isBotJoin = roomJoinNotice.IsBot || (!string.IsNullOrEmpty(roomJoinNotice.UserId) && roomJoinNotice.UserId.StartsWith("bot_")); @@ -523,6 +526,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base // 清除场景加载标记,下次进入可重新加载 Assets.MyGame.Scripts.Net.WebSocketReponseList.ClearLoadedGameScene(sceneName); WebSocketManager.Instance.Close(SocketType.game); + // ⭐ 座位镜像状态清空,下次进房重新按新房间座位 Setup + SeatMirror.Clear(); // ⭐ 重置本地道具计数,下次进入房间重新从服务端读取 _localBaoZouCount = -1; _localBingFengCount = -1; @@ -962,7 +967,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base // 同步给服务器:取消锁定 SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.changeAutoTarget, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeAutoTarget { targetGuid = null } @@ -1659,7 +1664,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base // 广播给其他客户端 SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.biaoQing, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_BiaoQing @@ -1696,11 +1701,13 @@ public class GameMainPanel_FishBase : GameMainPanel_Base /// 收到其他玩家发送表情的广播(biaoQing):在对应座位显示 public void SyncGameData_BiaoQing(SyncGameData sync) { - if (currSitData == null || sync.sitPos == currSitData.posID) return; // 本地座位已在发送时显示 + // ⭐ 座位镜像:服务端座位转显示座位 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (currSitData == null || dispPos == currSitData.posID) return; // 本地座位已在发送时显示 var data = FrameDataParser.Parse(sync.frameData); if (data == null) return; - ShowBiaoQing(sync.sitPos, data.biaoQingType, data.spineIndex, data.content); + ShowBiaoQing(dispPos, data.biaoQingType, data.spineIndex, data.content); } #endregion @@ -4026,7 +4033,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.rotateTurrect, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_Rotate { angle = angle } @@ -4057,7 +4064,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.fireBullet, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = fireData @@ -4093,7 +4100,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.changeAutoTarget, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeAutoTarget @@ -4108,7 +4115,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.changeTurretState, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_TurretState { state = state } @@ -4120,7 +4127,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.changeTurret, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeTurret { turretIndex = turretNumber } @@ -4133,7 +4140,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.changeWing, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeTurret { turretIndex = wingNumber } @@ -4147,7 +4154,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.changeZhanShen, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeTurret { turretIndex = zhanShenNumber } @@ -4160,7 +4167,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.freezeFish, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_FreezeFish { isFreeze = isFreeze } @@ -4174,9 +4181,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base #region ⑦ 服务器广播处理(NetReceiveModule) public void SyncGameData_Rotate(SyncGameData sync) { - if (sync.sitPos == currSitData.posID) return; + // ⭐ 座位镜像:网络 sitPos 是服务端空间,先转显示座位再比较/索引 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos == currSitData.posID) return; - var sit = list_Sits[sync.sitPos]; + var sit = list_Sits[dispPos]; // ⭐ 房主不处理机器人旋转广播:房主在 RotateBotToTarget 里已直接旋转本地炮台, // 再走 SmoothRotate 会和本地直接旋转冲突 if (sit != null && sit.isBot && currSitData == SitPosData.roomOwnerSit) return; @@ -4235,13 +4244,15 @@ public class GameMainPanel_FishBase : GameMainPanel_Base } var data = FrameDataParser.Parse(sync.extra.frameData); + // ⭐ 座位镜像:extra.sitPos 是发送方的服务端座位,转显示座位再索引 // ⭐ 边界检查:防止 sitPos 越界导致 IndexOutOfRangeException - if (sync.extra.sitPos < 0 || sync.extra.sitPos >= list_Sits.Count) + int dispPos = SeatMirror.ToDisplay(sync.extra.sitPos); + if (dispPos < 0 || dispPos >= list_Sits.Count) { Debug.LogWarning($"[SyncGameData_FireBullit] sitPos 越界: {sync.extra.sitPos}"); return; } - var targetSit = list_Sits[sync.extra.sitPos]; + var targetSit = list_Sits[dispPos]; FireBullet(targetSit, data.angle, data.isSanShe, data.twoRTruuect, data.isSuoDing, sync.bulletIds, data.monsterIDs, bulletGolds); } @@ -4252,9 +4263,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base public void SyncGameData_BotFireAngle(SyncGameData sync) { if (sync == null || sync.frameData == null) return; - if (sync.sitPos < 0 || sync.sitPos >= list_Sits.Count) return; + // ⭐ 座位镜像:bot 的服务端座位转显示座位 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos < 0 || dispPos >= list_Sits.Count) return; - var sit = list_Sits[sync.sitPos]; + var sit = list_Sits[dispPos]; if (sit == null || !sit.isBot) return; var fireData = FrameDataParser.Parse(sync.frameData); @@ -4266,13 +4279,15 @@ public class GameMainPanel_FishBase : GameMainPanel_Base public void SyncGameData_ChangeTargetMonster(SyncGameData sync) { - if (sync.sitPos == currSitData.posID) return; + // ⭐ 座位镜像:网络 sitPos 是服务端空间,先转显示座位再比较/索引 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos == currSitData.posID) return; var data = FrameDataParser.Parse(sync.frameData); if (data.targetGuid == null) { - list_Sits[sync.sitPos].ClearLock(); + list_Sits[dispPos].ClearLock(); return; } @@ -4283,7 +4298,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base // colliderList 顺序可能不一致,统一用"第一个活跃"更稳定 Transform hitPos = ResolveLockTransform(monster); - list_Sits[sync.sitPos].SetLockTarget(monster, hitPos); + list_Sits[dispPos].SetLockTarget(monster, hitPos); } public void SyncGameData_RendromDieFish(SyncGameData sync) @@ -4291,7 +4306,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base var data = JsonConvert.DeserializeObject(sync.frameData.ToString()); // 用 sync.sitPos 判断是否本地玩家发的(服务器不会丢这个字段) - bool isLocalSender = sync.sitPos == currSitData.posID; + // ⭐ 座位镜像:服务端座位转显示座位后再与本地显示座位比较 + bool isLocalSender = SeatMirror.ToDisplay(sync.sitPos) == currSitData.posID; CreateFishManager.Instance.Id_DieListFish_FX( data.guids, @@ -4305,52 +4321,62 @@ public class GameMainPanel_FishBase : GameMainPanel_Base public void SyncGameData_TurretState(SyncGameData sync) { - if (sync.sitPos == currSitData.posID) return; + // ⭐ 座位镜像:服务端座位转显示座位 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos == currSitData.posID) return; var data = FrameDataParser.Parse(sync.frameData); - var sit = list_Sits[sync.sitPos]; + var sit = list_Sits[dispPos]; sit.ChangeState(data.state); } public void SyncGameData_ChangeTurret(SyncGameData sync) { - if (sync.sitPos == currSitData.posID) return; + // ⭐ 座位镜像:服务端座位转显示座位 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos == currSitData.posID) return; var data = FrameDataParser.Parse(sync.frameData); - list_Sits[sync.sitPos].LoadTurret(data.turretIndex); + list_Sits[dispPos].LoadTurret(data.turretIndex); } public void SyncGameData_ChangeWing(SyncGameData sync) { - if (sync.sitPos == currSitData.posID) return; + // ⭐ 座位镜像:服务端座位转显示座位 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos == currSitData.posID) return; var data = FrameDataParser.Parse(sync.frameData); // turretIndex<=0 = 卸下翅膀;>0 = 加载对应编号翅膀(与战神 changeZhanShen 同一约定) if (data.turretIndex > 0) - list_Sits[sync.sitPos].LoadWing(data.turretIndex); + list_Sits[dispPos].LoadWing(data.turretIndex); else - list_Sits[sync.sitPos].ClearWing(); + list_Sits[dispPos].ClearWing(); } public void SyncGameData_ChangeZhanShen(SyncGameData sync) { - if (sync.sitPos == currSitData.posID) return; + // ⭐ 座位镜像:服务端座位转显示座位 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos == currSitData.posID) return; var data = FrameDataParser.Parse(sync.frameData); // turretIndex<=0 = 卸下战神;>0 = 加载对应编号战神(内部会隐藏该座位的普通炮台) if (data.turretIndex > 0) - list_Sits[sync.sitPos].LoadZhanShen(data.turretIndex); + list_Sits[dispPos].LoadZhanShen(data.turretIndex); else - list_Sits[sync.sitPos].ClearZhanShen(); + list_Sits[dispPos].ClearZhanShen(); } public void SyncGameData_ChangeCannonMultiple(SyncGameData sync) { - if (sync.sitPos == currSitData.posID) return; + // ⭐ 座位镜像:服务端座位转显示座位 + int dispPos = SeatMirror.ToDisplay(sync.sitPos); + if (dispPos == currSitData.posID) return; var data = FrameDataParser.Parse(sync.frameData); - var sit = list_Sits[sync.sitPos]; + var sit = list_Sits[dispPos]; sit.consumeGoldNum = data.cannonMultiple; sit.tMP_TurretConsumeNum.text = data.cannonMultiple.ToString(); } @@ -4397,7 +4423,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base if (currSitData == null) return; SyncGameData sgd = new SyncGameData { - sitPos = currSitData.posID, + sitPos = SeatMirror.ToServer(currSitData.posID), frameType = FrameDataType.changeCannonMultiple, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeCannonMultiple { cannonMultiple = consumeGold } @@ -4551,9 +4577,13 @@ public class GameMainPanel_FishBase : GameMainPanel_Base public void JoinGame(int sitNum, long goldNum, long diamondNum, long consumeGold, int currentTurretIndex, string user = null, string cannonId = null, string wingId = null, string warGodId = null) { + // ⭐ 座位镜像:调用方传的是服务端座位号(RoomJoinNotice.Position / players[].position), + // 转成本地视角的显示座位再匹配场景座位(本地在上方时 0↔2、1↔3 对调) + int displayPos = SeatMirror.ToDisplay(sitNum); + foreach (var sit in list_Sits) { - if (sit.posID != sitNum) continue; + if (sit.posID != displayPos) continue; // ⭐ 确保座位 GameObject 本身是激活的(可能被 HandleBotExit 隐藏或初始为 inactive) if (!sit.gameObject.activeSelf) @@ -4964,7 +4994,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base // 接收端 SyncGameData_ChangeCannonMultiple 会根据 sitPos 更新对应座位 var sgd = new SyncGameData { - sitPos = sit.posID, + sitPos = SeatMirror.ToServer(sit.posID), frameType = FrameDataType.changeCannonMultiple, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeCannonMultiple { cannonMultiple = (int)sit.consumeGoldNum } @@ -5345,7 +5375,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { SyncGameData sgd = new SyncGameData { - sitPos = botSit.posID, + sitPos = SeatMirror.ToServer(botSit.posID), frameType = FrameDataType.rotateTurrect, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_Rotate { angle = angle } @@ -5374,7 +5404,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base SyncGameData sgd = new SyncGameData { - sitPos = botSit.posID, + sitPos = SeatMirror.ToServer(botSit.posID), frameType = FrameDataType.changeAutoTarget, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeAutoTarget @@ -5403,7 +5433,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base SyncGameData sgd = new SyncGameData { - sitPos = botSit.posID, + sitPos = SeatMirror.ToServer(botSit.posID), frameType = FrameDataType.changeTurretState, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_TurretState { state = state } @@ -5429,7 +5459,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base SyncGameData sgd = new SyncGameData { - sitPos = botSit.posID, + sitPos = SeatMirror.ToServer(botSit.posID), frameType = FrameDataType.fireBullet, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = fireData diff --git a/Assets/MyGame/aa/UI/Game/SeatMirror.cs b/Assets/MyGame/aa/UI/Game/SeatMirror.cs new file mode 100644 index 000000000..09c46d2df --- /dev/null +++ b/Assets/MyGame/aa/UI/Game/SeatMirror.cs @@ -0,0 +1,70 @@ +// ============================================================ +// 文件:SeatMirror.cs +// 职责:4人捕鱼桌座位镜像转换(玩家永远看自己在下方) +// +// 座位定义(服务端与场景一致): +// 0 = 左下 1 = 右下 +// 2 = 左上 3 = 右上 +// +// 镜像规则: +// 本地玩家分到上方座位(2/3)时,整个桌面上下翻转显示: +// 显示座位 = 服务端座位 XOR 2(0↔2、1↔3 对调),本地玩家落回下方。 +// 本地玩家在下方座位(0/1)时不镜像,显示 = 服务端。 +// +// 两个坐标空间(必须严格区分,跨界必经本类转换): +// - 服务端空间(server):网络协议字段 SyncGameData.sitPos / RoomJoinNotice.Position +// / players[].position,服务端只认这个空间。 +// - 显示空间(display):场景座位 SitPosData.posID 及一切本地表现 +// (炮台朝向 IsFlipped、锁定圈、金币飞、bot AI 等)。 +// SitPosData.posID 永远是显示座位,场景预制体不用动。 +// +// 收发转换口诀: +// 收到网络数据(含 sitPos/position)→ 先 ToDisplay 再找场景座位; +// 向服务端发数据(含 sitPos)→ 用 ToServer 把显示座位转回服务端座位。 +// ============================================================ +public static class SeatMirror +{ + /// 本地玩家在服务端的座位号(OnShow 收到 RoomJoinNotice 时 Setup;-1=未初始化/已离房) + public static int LocalServerPos { get; private set; } = -1; + + /// 是否镜像生效(本地分到上方座位 2/3) + public static bool IsMirrored => LocalServerPos >= 2; + + /// + /// 进房时设置本地服务端座位号(决定是否镜像)。 + /// GameMainPanel_FishBase.OnShow 解析出 RoomJoinNotice 后第一时间调用; + /// 切换房间会重新调用(新房间座位可能变化)。 + /// + public static void Setup(int localServerPos) + { + LocalServerPos = localServerPos; + UnityEngine.Debug.Log($"[SeatMirror] 本地服务端座位={localServerPos} " + + (IsMirrored ? "→ 在上方,启用全桌上下镜像(0↔2,1↔3)" : "→ 在下方,不镜像")); + } + + /// 离房时清空(OnHide 调用),防止跨房间残留旧镜像状态 + public static void Clear() + { + LocalServerPos = -1; + } + + /// + /// 服务端座位 → 显示座位(本地视角)。 + /// 用于:接收网络数据后定位场景座位、给玩家分配 SitPosData、RoomJoinNotice/RoomChange 的 position。 + /// 越界值原样返回(防御:后端异常数据不误转换)。 + /// + public static int ToDisplay(int serverPos) + { + if (serverPos < 0 || serverPos > 3 || !IsMirrored) return serverPos; + return serverPos ^ 2; // 0↔2、1↔3 上下对调 + } + + /// + /// 显示座位 → 服务端座位(发送网络数据时用)。 + /// XOR 2 自反,与 ToDisplay 互逆。 + /// + public static int ToServer(int displayPos) + { + return ToDisplay(displayPos); + } +} diff --git a/Assets/MyGame/aa/UI/Game/SeatMirror.cs.meta b/Assets/MyGame/aa/UI/Game/SeatMirror.cs.meta new file mode 100644 index 000000000..3933f98c5 --- /dev/null +++ b/Assets/MyGame/aa/UI/Game/SeatMirror.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c45f7e3e9e6ed784eb872e39cbbc62e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: