4坐座位
This commit is contained in:
Binary file not shown.
@@ -1556,7 +1556,8 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
// ⭐ 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<CreateFishManager>
|
||||
{
|
||||
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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -653,7 +653,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 810
|
||||
depthOffset: 890
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -704,7 +704,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 1
|
||||
ischild0: 1
|
||||
depthOffset: 820
|
||||
depthOffset: 880
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -710,7 +710,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 840
|
||||
depthOffset: 860
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -698,7 +698,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: -850
|
||||
depthOffset: 850
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -394,7 +394,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 1
|
||||
ischild0: 1
|
||||
depthOffset: 860
|
||||
depthOffset: 840
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -426,7 +426,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 870
|
||||
depthOffset: 770
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -908,7 +908,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 890
|
||||
depthOffset: 810
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -289,7 +289,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 1000
|
||||
depthOffset: 900
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -350,7 +350,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 830
|
||||
depthOffset: 870
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -506,7 +506,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 880
|
||||
depthOffset: 820
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -760,7 +760,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 900
|
||||
depthOffset: 800
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -1099,7 +1099,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 910
|
||||
depthOffset: 790
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -464,7 +464,7 @@ MonoBehaviour:
|
||||
isRotate: 1
|
||||
isNot1: 0
|
||||
ischild0: 1
|
||||
depthOffset: 920
|
||||
depthOffset: 780
|
||||
is2DFish: 0
|
||||
sortOrder2D: 0
|
||||
drawMoveLine: 0
|
||||
|
||||
@@ -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
|
||||
/// <summary>收到其他玩家发送表情的广播(biaoQing):在对应座位显示</summary>
|
||||
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<FrameData_BiaoQing>(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<FrameData_FireBullet>(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<FrameData_FireBullet>(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<FrameData_ChangeAutoTarget>(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<FrameData_RandomDieFish>(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<FrameData_TurretState>(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<FrameData_ChangeTurret>(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<FrameData_ChangeTurret>(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<FrameData_ChangeTurret>(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<FrameData_ChangeCannonMultiple>(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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>本地玩家在服务端的座位号(OnShow 收到 RoomJoinNotice 时 Setup;-1=未初始化/已离房)</summary>
|
||||
public static int LocalServerPos { get; private set; } = -1;
|
||||
|
||||
/// <summary>是否镜像生效(本地分到上方座位 2/3)</summary>
|
||||
public static bool IsMirrored => LocalServerPos >= 2;
|
||||
|
||||
/// <summary>
|
||||
/// 进房时设置本地服务端座位号(决定是否镜像)。
|
||||
/// GameMainPanel_FishBase.OnShow 解析出 RoomJoinNotice 后第一时间调用;
|
||||
/// 切换房间会重新调用(新房间座位可能变化)。
|
||||
/// </summary>
|
||||
public static void Setup(int localServerPos)
|
||||
{
|
||||
LocalServerPos = localServerPos;
|
||||
UnityEngine.Debug.Log($"[SeatMirror] 本地服务端座位={localServerPos} " +
|
||||
(IsMirrored ? "→ 在上方,启用全桌上下镜像(0↔2,1↔3)" : "→ 在下方,不镜像"));
|
||||
}
|
||||
|
||||
/// <summary>离房时清空(OnHide 调用),防止跨房间残留旧镜像状态</summary>
|
||||
public static void Clear()
|
||||
{
|
||||
LocalServerPos = -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务端座位 → 显示座位(本地视角)。
|
||||
/// 用于:接收网络数据后定位场景座位、给玩家分配 SitPosData、RoomJoinNotice/RoomChange 的 position。
|
||||
/// 越界值原样返回(防御:后端异常数据不误转换)。
|
||||
/// </summary>
|
||||
public static int ToDisplay(int serverPos)
|
||||
{
|
||||
if (serverPos < 0 || serverPos > 3 || !IsMirrored) return serverPos;
|
||||
return serverPos ^ 2; // 0↔2、1↔3 上下对调
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示座位 → 服务端座位(发送网络数据时用)。
|
||||
/// XOR 2 自反,与 ToDisplay 互逆。
|
||||
/// </summary>
|
||||
public static int ToServer(int displayPos)
|
||||
{
|
||||
return ToDisplay(displayPos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c45f7e3e9e6ed784eb872e39cbbc62e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user