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);