1
This commit is contained in:
@@ -194,6 +194,15 @@ public class MonsterContral : MonoBehaviour
|
||||
/// <summary>路径已行进的时间(秒),用于B样曲线插值;可由外部预设偏移实现同步追帧。</summary>
|
||||
public float moveTime = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// 阵鱼(700/701)创建时刻偏移(秒):由生成端填入"该鱼创建时刻 - 本次鱼阵开始时刻"。
|
||||
/// 位移公式里用 (moveTime + yzGroupTimeOffset) 取代 moveTime,
|
||||
/// 使先创建的那一组已经沿分布方向游出去、后创建的从出生点出发,
|
||||
/// 避免多个 组/鱼 全部重合在同一个出生点上。
|
||||
/// ⭐ 与 moveTime 分开:偏移只影响初始位置,不影响存活时长(moveTime 仍从 0 计时)。
|
||||
/// </summary>
|
||||
public float yzGroupTimeOffset = 0f;
|
||||
|
||||
/// <summary>是否为鱼阵成员</summary>
|
||||
public bool isyz = false;
|
||||
|
||||
@@ -395,6 +404,7 @@ public class MonsterContral : MonoBehaviour
|
||||
uirootRect = UIManager.Instance.uiRoot.GetComponent<RectTransform>();
|
||||
mainCamera = Camera.main;
|
||||
moveTime = 0f;
|
||||
yzGroupTimeOffset = 0f; // 池复用清掉上次的阵鱼创建偏移
|
||||
// ⭐ 重置创建视频状态:池回收的鱼 _isPlayingCreateVideo 可能残留 true,
|
||||
// 重新生成时重置,由 Init 决定是否重新播放
|
||||
_createVideoDuration = 0f;
|
||||
@@ -718,7 +728,8 @@ public class MonsterContral : MonoBehaviour
|
||||
// 扇形/圈的阵型靠生成端分布角实现,移动方向必须与之一致;
|
||||
// _yzMoveDir 在 CacheYzLineMoveData 里按轴读生成姿态前方,投影过短回退(0,±1)
|
||||
Vector2 lineDir = _yzMoveDir;
|
||||
Vector2 pos = (Vector2)_yzStartWorld + lineDir * moveTime * monsterData.moveLine.moveTime;
|
||||
// ⭐ 加上创建时刻偏移:先创建的组已经游出去,后创建的从出生点出发,避免重合在同一点
|
||||
Vector2 pos = (Vector2)_yzStartWorld + lineDir * (moveTime + yzGroupTimeOffset) * monsterData.moveLine.moveTime;
|
||||
|
||||
// ⭐ 朝向保持生成姿态(分布角)不转——不调 ApplyFacingDirection:
|
||||
// 它会覆盖根的分布角,把扇形/圈抹成一列竖队
|
||||
@@ -746,7 +757,8 @@ public class MonsterContral : MonoBehaviour
|
||||
|
||||
// ⭐ 同缓存分支:沿分布方向移动(缓存值优先,未初始化回退固定垂直),朝向不转
|
||||
Vector2 lineDir = _yzMoveDir != Vector2.zero ? _yzMoveDir : new Vector2(0f, dir);
|
||||
Vector2 pos = (Vector2)startWorld + lineDir * moveTime * monsterData.moveLine.moveTime;
|
||||
// ⭐ 兜底分支同样加上创建时刻偏移(与缓存分支一致)
|
||||
Vector2 pos = (Vector2)startWorld + lineDir * (moveTime + yzGroupTimeOffset) * monsterData.moveLine.moveTime;
|
||||
|
||||
// ⭐ 保留根节点当前 z(2D 小鱼 z 一直为 0,行为不变)
|
||||
transform.position = new Vector3(pos.x, pos.y, transform.position.z);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user