This commit is contained in:
2026-10-01 03:26:35 +08:00
parent 7187549893
commit 4d8ec49055
2 changed files with 68 additions and 13 deletions
@@ -222,6 +222,17 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
// fangzhu 字段已删除:鱼创建改由服务端 OnFishSpawn 统一下发,客户端无需房主出鱼
public bool isResources = false;
[Header("扇形阵(700)")]
[Tooltip("同一扇内相邻两条鱼之间的生成间隔(秒),避免17条鱼同帧出生叠在一起")]
public float shanXingFishInterval = 0.05f;
[Header("鱼阵路线撞车")]
[Tooltip("同一条路线被鱼阵占用后,其他鱼阵再用到同一条线需要等待的秒数(避免同一出生点同帧重叠)")]
public float lineConflictCooldown = 1f;
/// <summary>每条鱼阵路线最近一次被鱼阵占用的时刻(Time.time),用于同线撞车延迟</summary>
private readonly Dictionary<int, float> _lineBusyTime = new Dictionary<int, float>();
/// <summary>
/// 鱼阵实例全局计数器,每次 SpawnFishArray 递增。
/// 用于生成全局唯一 guid,防止 pathList 重复 pathId 或同 fishId 多次推送导致 guid 冲突。
@@ -449,6 +460,13 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
InitSpawnSystem(gameType);
BindCurrentGamePanel();
EnsureBJEffectRoot();
_lineBusyTime.Clear(); // 清掉上个房间的路线占用记录
// ⭐ 必须先把 isResources 置 true 再回放:
// 调用方( GameMainPanel_FishBase )是在 EnterRoom 之后才置 true 的,
// 而鱼阵协程(IeShanXing/IeQuan/YZ7007)里都有 `if (!isResources) yield break;`,
// 回放时它还是 false(退房残留)→ 服务端进房瞬间推的初始鱼阵(init/sync)
// 全部 ARRAY_ENTER 后一条鱼都不生成,进房看不到鱼阵
isResources = true;
// ⭐ 回放进房加载期间收到的出鱼事件(服务端进房瞬间推的 init/sync 初始鱼)
FlushPendingFishSpawns();
}
@@ -1188,12 +1206,32 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
{
yield break;
}
ShanXing(createFishData, yz, pos, prefab, pathList[lineIndex], count, time, arraySeq, lineIndex);
// ⭐ 同线撞车:这条线刚被别的鱼阵用过时先等一会,避免同一出生点同帧叠一起
yield return WaitLineFree(pathList[lineIndex]);
yield return ShanXing(createFishData, yz, pos, prefab, pathList[lineIndex], count, time, arraySeq, lineIndex);
yield return new WaitForSeconds(1f);
}
}
private void ShanXing(FrameData_CreateFish createFishData, FishArrayConfig yz,
/// <summary>
/// 同线撞车等待:某条鱼阵路线在 lineConflictCooldown 秒内刚被鱼阵占用过,
/// 就等到冷却结束再发射;返回后立刻把该线标记为占用。
/// ⭐ 进房时服务端会一口气推十几个鱼阵,很容易两个阵落在同一条线上,
/// 同帧同出生点出发必然重叠,靠这个把后出的推到 1 秒后。
/// </summary>
private IEnumerator WaitLineFree(int pathId)
{
if (lineConflictCooldown > 0f && _lineBusyTime.TryGetValue(pathId, out float last))
{
float wait = lineConflictCooldown - (Time.time - last);
if (wait > 0f && isResources)
yield return new WaitForSeconds(wait);
}
_lineBusyTime[pathId] = Time.time;
}
/// <summary>扇形阵:一条线的17条鱼按 shanXingFishInterval 逐条延迟生成(避免同帧出生叠在一起)。</summary>
private IEnumerator ShanXing(FrameData_CreateFish createFishData, FishArrayConfig yz,
Vector3 pos, GameObject prefab, int pathId, int count, long time, int arraySeq, int lineIndex)
{
var cfg = spawnDic[createFishData.fishNumber];
@@ -1227,25 +1265,31 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
mc.guid = createFishData.guid + "_" + arraySeq + "_" + lineIndex + "_" + i;
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
// ⭐ moveTime 归零(存活时长从本条鱼自己出生算起),
// "创建时刻偏移"单独放进 yzGroupTimeOffset:它只进位移公式,
// 让先出的那一组已经沿分布方向游出去、后出的从出生点出发,避免整组重叠在同一点
mc.moveTime = 0f;
mc.yzGroupTimeOffset = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
mc.Init(pathId.ToString(), cfg.times, true, yz.arrayNumber);
// ⭐ 鱼阵调试日志:输出每条子鱼生成后的旋转与缩放(排查"有的正有的反")
Debug.Log($"[鱼阵调试] 阵={yz.arrayNumber}(扇形700) pathId={pathId} 第{i}/{16}条 guid={mc.guid} " +
$"rotation={fish.transform.eulerAngles.ToString("F1")} localScale={fish.transform.localScale.ToString("F3")}");
// ⭐ 同一扇内逐条延迟:避免17条鱼同帧出生全叠在出生点
yield return new WaitForSeconds(shanXingFishInterval);
}
}
/// <summary>
/// 环形阵:按路线列表遍历生成圈。
/// 正常无延迟(同帧出);⭐ 同一鱼阵内出现重复的同一条线(同一出生点)时,
/// 延迟 1s 再发射,避免两圈叠在出生点。
/// 正常无延迟(同帧出);⭐ 同一条线(lineConflictCooldown 秒内)刚被鱼阵用过时,
/// 等待冷却再发射,避免两圈叠在同一出生点(含鱼阵内重复线、不同鱼阵撞线)。
/// </summary>
private IEnumerator IeQuan(FrameData_CreateFish createFishData, FishArrayConfig yz,
Vector3 pos, GameObject prefab, List<int> pathList, long time, int count, int arraySeq)
{
var usedLines = new HashSet<int>();
for (int lineIndex = 0; lineIndex < pathList.Count; lineIndex++)
{
if (!isResources)
@@ -1254,10 +1298,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
}
int pathId = pathList[lineIndex];
// ⭐ 该线本次鱼阵已出现过(同一出生点):延迟 1s 再发射
if (!usedLines.Add(pathId))
yield return new WaitForSeconds(1f);
yield return WaitLineFree(pathId);
Quan(createFishData, yz, pos, prefab, pathId, count, time, arraySeq, lineIndex);
}
}
@@ -1290,7 +1331,9 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
mc.guid = createFishData.guid + "_" + arraySeq + "_" + lineIndex + "_" + i;
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
// ⭐ moveTime 归零 + 创建时刻偏移进 yzGroupTimeOffset(说明同扇形)
mc.moveTime = 0f;
mc.yzGroupTimeOffset = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
mc.Init(pathId.ToString(), cfg.times, true, yz.arrayNumber);