This commit is contained in:
2026-07-27 16:59:22 +08:00
parent 48863cc4f8
commit 738b2b2d36
11 changed files with 298 additions and 89 deletions
@@ -112,6 +112,10 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
public bool isCreateFish; //是否可以创建鱼
public bool isFrozen = false; //是否冰冻中(冻结出鱼+所有鱼定格)
[Header("调试:手动出鱼")]
[Tooltip("按 M 键生成的鱼编号(配置 fishNumber)")]
public string debugSpawnFishNumber = "11043";
private Dictionary<string, CharacterStateType> frozenFishStates = new Dictionary<string, CharacterStateType>();
private Dictionary<string, bool> frozenFishIsMoves = new Dictionary<string, bool>();
@@ -249,7 +253,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
if (fishRoot == null)
fishRoot = new GameObject("FishRoot").transform;
if (poolRoot == null)
fishRoot = new GameObject("poolRoot").transform;
poolRoot = new GameObject("poolRoot").transform;
// ⭐ 鱼创建改由服务端 OnFishSpawn 事件统一下发,客户端不再监听 createFish 帧同步
EventCenter.Instance.AddEventListener<OnFishSpawnData>(
@@ -264,6 +268,19 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
{
// 鱼创建由服务端 OnFishSpawn 事件驱动,客户端 Update 不再出鱼
// (保留 isFrozen 字段供 FreezeAllFish/UnfreezeAllFish 使用)
// ⭐ 调试用:按 M 键手动出鱼(出 Inspector 配置的 debugSpawnFishNumber)
// 使用新版输入系统(Input System):Keyboard.current.wasPressedThisFrame
if (UnityEngine.InputSystem.Keyboard.current != null &&
UnityEngine.InputSystem.Keyboard.current.mKey.wasPressedThisFrame)
{
if (string.IsNullOrEmpty(debugSpawnFishNumber))
{
Debug.LogWarning("[CreateFishManager] 未配置 debugSpawnFishNumber,请在 Inspector 设置鱼编号");
return;
}
ManualSpawn(debugSpawnFishNumber);
}
}
@@ -612,11 +629,14 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
foreach (var item in data.fish)
{
if (item == null) continue;
Debug.Log("差值:"+(BeijingTimeManager.Instance.CurrentTimestampMs-item.createdAt)/1000/60);
Debug.Log("差值:"+(BeijingTimeManager.Instance.CurrentTimestampMs-item.createdAt)/1000);
Debug.Log("差值:"+(BeijingTimeManager.Instance.CurrentTimestampMs-item.createdAt));
Debug.Log("差值:"+BeijingTimeManager.Instance.CurrentTimestampMs+"创建\n"+item.createdAt);
if (string.IsNullOrEmpty(item.fishNumber)) continue;
// ⭐ 鱼阵时 fishNumber 为空,用 fishArrayNumber 作为配置 key;
// 单体鱼时 fishNumber 非空,直接用 fishNumber
string cfgKey = string.IsNullOrEmpty(item.fishNumber) ? item.fishArrayNumber : item.fishNumber;
if (string.IsNullOrEmpty(cfgKey)) continue;
// guid 用服务端 fishId
string guid = item.fishId.ToString();
@@ -629,19 +649,28 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
// 构造 FrameData_CreateFish 复用 SpawnFishMainThread
var createFishData = new FrameData_CreateFish
{
fishNumber = item.fishNumber,
fishNumber = cfgKey,
guid = guid,
moveLineId = item.routeId.ToString()
};
// ⭐ 用 item.createdAt(鱼创建时间)算 moveTime,而非 data.timestamp(事件下发时间)
// spawn 模式两者接近,但 sync 模式同步已存在的鱼时 createdAt 早于 timestamp,
// 时间差让鱼出现在路径正确位置(而非从起点重新游)
SpawnFishMainThread(createFishData, item.createdAt);
// ⭐ 根据 type 决定 moveTime:
// - spawn/init:新鱼,传当前时间 → moveTime≈0,鱼从曲线起点开始游
// (避免服务端/客户端时间差导致 moveTime>0,鱼瞬间出现在曲线中间)
// - sync:同步已有鱼,传 createdAt → moveTime=时间差,鱼出现在路径正确位置
long spawnTime;
//if (data.type == "sync")
spawnTime = item.createdAt;
//else
// spawnTime = BeijingTimeManager.Instance.CurrentTimestampMs;
SpawnFishMainThread(createFishData, spawnTime);
// expireAt 到期自动移除(remainingSeconds 秒后销毁)
if (item.remainingSeconds > 0)
StartCoroutine(ExpireFishCoroutine(guid, item.remainingSeconds));
// ⭐ expireAt 过期自动移除暂不启用:
// - 走路线的鱼:OnMoveUpdata 里 moveTime>=moveLine.moveTime 时自动 Id_DieFish_NotFX
// - 原点不动的鱼(Boss):正常播放结束动画后销毁
// 后续若需要服务端强制过期销毁,再启用此协程
// if (item.remainingSeconds > 0)
// StartCoroutine(ExpireFishCoroutine(guid, item.remainingSeconds));
}
Debug.Log($"[CreateFishManager] OnFishSpawn type={data.type}, count={data.fish.Count}");
@@ -656,6 +685,45 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
yield return new WaitForSeconds(remainingSeconds);
Id_DieFish_NotFX(guid);
}
/// <summary>
/// 手动出鱼(测试/调试用,不走服务端协议)。
/// 用当前时间作为 spawnTime → moveTime≈0,鱼从曲线起点开始游。
/// </summary>
/// <param name="fishNumber">鱼编号(配置 fishNumber)</param>
/// <param name="routeId">路径编号,<=0 时随机取一条</param>
/// <param name="remainingSeconds">鱼存活秒数,<=0 时默认 30 秒</param>
/// <returns>生成成功返回 true,失败返回 false</returns>
public bool ManualSpawn(string fishNumber, int routeId = 0, int remainingSeconds = 30)
{
if (isFrozen) { Debug.LogWarning("[CreateFishManager] 冰冻中,手动出鱼失败"); return false; }
if (spawnDic == null) { Debug.LogWarning("[CreateFishManager] spawnDic 未初始化,手动出鱼失败"); return false; }
if (string.IsNullOrEmpty(fishNumber)) { Debug.LogWarning("[CreateFishManager] fishNumber 为空,手动出鱼失败"); return false; }
if (!spawnDic.ContainsKey(fishNumber)) { Debug.LogWarning($"[CreateFishManager] 找不到鱼配置: {fishNumber},手动出鱼失败"); return false; }
// routeId<=0 时随机取一条路线(1~4 范围,按现有路线命名规则)
if (routeId <= 0)
routeId = Random.Range(1, 5);
// 生成唯一 guid(用手动出鱼前缀 + 时间戳,避免与服务端 fishId 冲突)
string guid = "manual_" + BeijingTimeManager.Instance.CurrentTimestampMs + "_" + Random.Range(1000, 9999);
var createFishData = new FrameData_CreateFish
{
fishNumber = fishNumber,
guid = guid,
moveLineId = routeId.ToString()
};
// 用当前时间 → moveTime≈0,鱼从曲线起点开始游
SpawnFishMainThread(createFishData, BeijingTimeManager.Instance.CurrentTimestampMs);
//if (remainingSeconds > 0)
// StartCoroutine(ExpireFishCoroutine(guid, remainingSeconds));
Debug.Log($"[CreateFishManager] 手动出鱼: fishNumber={fishNumber}, routeId={routeId}, guid={guid}");
return true;
}
#endregion
#region 旧客户端出鱼链路(已删除)