diff --git a/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs b/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs
index 1aa2c34c8..3cc0fe13f 100644
--- a/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs
+++ b/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs
@@ -47,6 +47,9 @@ public class MonsterContral : MonoBehaviour
/// 本鱼唯一标识(服务器下发的 GUID)
public string guid;
+ /// 当前鱼使用的路线 ID(Init 时保存,用于房主把活鱼广播给新加入玩家)
+ public string lastMoveLineId;
+
/// 运行时数据(血量、路径、配置等)
public MonsterDataBase monsterData = new MonsterDataBase(new MonsterHealthBase());
@@ -198,6 +201,9 @@ public class MonsterContral : MonoBehaviour
/// 鱼阵 ID(isyuzhen==true 时有效)
public virtual void Init(string pathId, float time, bool isyuzhen = false, string yzID = "")
{
+ // ⭐ 保存 pathId,用于房主把活鱼广播给新加入玩家
+ lastMoveLineId = pathId;
+
// 根据是否为鱼阵选择路线 key
string lineKey = isyuzhen
? YzMoveLineName + pathId
diff --git a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs
index bb46a2581..b0e05373a 100644
--- a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs
+++ b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs
@@ -1106,6 +1106,62 @@ public class CreateFishManager : MonoSingleton
Debug.Log($"[CreateFishManager] 初始鱼已广播: {count} 条 (房主,走原有出鱼机制)");
}
+
+ ///
+ /// 房主把当前场上所有活鱼广播一遍,用于新玩家加入房间时同步场上鱼状态。
+ /// 直接遍历 fishDatas_hashCodekey(全部活鱼),反推 time 字段让新玩家收到后
+ /// 通过 (CurrentTimestampMs - time)/1000f 算出与房主一致的 moveTime,
+ /// 鱼会出现在路径的正确中段位置,与老玩家看到的一致。
+ /// guid 复用原 guid,保证后续杀鱼/锁定帧同步不会失同步。
+ ///
+ public void BroadcastExistingFishes()
+ {
+ if (!fangzhu) return;
+ if (fishDatas_hashCodekey == null || fishDatas_hashCodekey.Count == 0) return;
+
+ // ⭐ 复制一份快照,避免遍历过程中鱼死亡修改字典导致 InvalidOperationException
+ var snapshot = new List>(fishDatas_hashCodekey);
+ long nowMs = BeijingTimeManager.Instance.CurrentTimestampMs;
+ int count = 0;
+
+ foreach (var kv in snapshot)
+ {
+ var mc = kv.Value;
+ if (mc == null) continue;
+ if (mc.monsterData == null || mc.monsterData.fishTypeConfig == null) continue;
+ if (mc.monsterData.moveLine == null) continue;
+ if (string.IsNullOrEmpty(mc.guid)) continue;
+ if (string.IsNullOrEmpty(mc.lastMoveLineId)) continue;
+
+ // 总时长,用于过滤快死的鱼(避免新玩家刚进入就看到鱼死)
+ float totalTime = mc.monsterData.moveLine.moveTime;
+ if (totalTime <= 0f) continue;
+ // 跳过还没初始化的鱼(moveTime < 0)和快死的鱼(进度 >= 0.9)
+ if (mc.moveTime < 0f) continue;
+ if (mc.moveTime >= totalTime * 0.9f) continue;
+
+ // ⭐ 反推 sendTime:让新玩家收到后 (CurrentTimestampMs - sendTime)/1000f ≈ mc.moveTime
+ long sendTime = nowMs - (long)(mc.moveTime * 1000f);
+
+ var sgd = new SyncGameData
+ {
+ sitPos = GameManager.Instance.gameData.roomJoinNotice.position,
+ frameType = FrameDataType.createFish,
+ time = sendTime,
+ frameData = new FrameData_CreateFish
+ {
+ fishNumber = mc.monsterData.fishTypeConfig.fishNumber,
+ guid = mc.guid, // ⭐ 复用原 guid
+ moveLineId = mc.lastMoveLineId
+ }
+ };
+
+ WebSocketSendList.SyncGameData(sgd);
+ count++;
+ }
+
+ Debug.Log($"[CreateFishManager] 广播场上活鱼: {count} 条 (房主,新玩家加入同步)");
+ }
#endregion
#region 创建鱼
@@ -1740,7 +1796,6 @@ public class CreateFishManager : MonoSingleton
// sitData.tMP_GoldNum.text = sitData.goldNum.ToString();
// AudioManager.Instance.PlayerFX(audioID);
//};
- monster.DieFish(killFish);
switch (monster.fishenum)
{
@@ -1906,6 +1961,8 @@ public class CreateFishManager : MonoSingleton
default:
break;
}
+ monster.DieFish(killFish);
+
MonsterDieList.Instance.SmallHuangYiHuang(
monster.transform.position,
monster.monsterData.fishTypeConfig.fishNumber, 1000);
diff --git a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs
index c68852426..dcd989c6b 100644
--- a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs
+++ b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs
@@ -286,6 +286,12 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
targetSit.isBot = false;
targetSit.ShowWaiting();
}
+ // ⭐ 房主:新真人玩家加入时,把当前场上所有活鱼广播一遍,
+ // 让新玩家立即同步看到场上鱼状态(不用等房主下次出鱼)
+ if (CreateFishManager.Instance != null && CreateFishManager.Instance.fangzhu)
+ {
+ CreateFishManager.Instance.BroadcastExistingFishes();
+ }
}
JoinGame(roomJoinNotice.position, roomJoinNotice.gold, roomJoinNotice.diamond, roomJoinNotice.cannonMultiple, 0, roomJoinNotice.userId, roomJoinNotice.cannonId, roomJoinNotice.wingsId);