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
+15 -2
View File
@@ -60,6 +60,15 @@ public class Pool : Singleton<Pool>
{
public Dictionary<int, PoolData> dic = new Dictionary<int, PoolData>();//生成一个字典
private GameObject poolObj;//Scene窗口中的“pool”总收纳盒
/// <summary>获取/创建池总父节点(初始化和 Return 共用同一个 poolObj)</summary>
public GameObject EnsurePoolRoot()
{
if (poolObj == null)
poolObj = new GameObject("pool");
return poolObj;
}
public GameObject Get(int id, Vector3 position, Quaternion rotation)//返回一个预制体,
{
GameObject obj;
@@ -116,6 +125,7 @@ public class Pool : Singleton<Pool>
{
if(obj.activeSelf)
{
// ⭐ 统一用 poolObj 作为池总父节点(初始化时也用 poolObj,保证 Clear 能统一销毁)
if(poolObj==null)
{
poolObj = new GameObject("pool");
@@ -133,7 +143,7 @@ public class Pool : Singleton<Pool>
}
return obj;
}
//public void Clear()//切换场景时将所有缓存清除
//{
// dic.Clear();
@@ -144,9 +154,12 @@ public class Pool : Singleton<Pool>
/// </summary>
public void Clear()
{
// ⭐ 防重入:已经清空过直接返回
if (dic.Count == 0 && poolObj == null) return;
foreach (var kv in dic.Values)
{
kv.Clear();
if (kv != null) kv.Clear();
}
dic.Clear();
+27 -30
View File
@@ -82,10 +82,14 @@ public class BeijingTimeManager : MonoSingleton<BeijingTimeManager>
foreach (string url in timeServers)
{
// 记录请求开始时间,用于 RTT 补偿
DateTime requestStartTime = DateTime.Now;
using (UnityWebRequest request = UnityWebRequest.Get(url + "?_=" + DateTime.Now.Ticks))
{
request.timeout = 5;
yield return request.SendWebRequest();
// 收到响应的本地时间
DateTime requestEndTime = DateTime.Now;
if (request.result == UnityWebRequest.Result.Success)
{
@@ -101,21 +105,20 @@ public class BeijingTimeManager : MonoSingleton<BeijingTimeManager>
try
{
JObject json = JObject.Parse(jsonText);
DateTime? serverTime = null;
if (url.Contains("47.109.132.12"))
{
// 返回格式:{"data":{"dateTime":"2026-07-26 20:02:48",...},"code":0,"info":null}
// 返回格式:{"data":{"dateTime":"2026-07-26 20:02:48","milliSeconds":330,...},"code":0,"info":null}
// dateTime 只精确到秒,需要补 milliSeconds 字段
string timeStr = json["data"]?["dateTime"]?.ToString();
Debug.Log($"47.109.132.12 提取到的时间字符串:{timeStr}");
int ms = json["data"]?["milliSeconds"]?.Value<int>() ?? 0;
Debug.Log($"47.109.132.12 提取到的时间字符串:{timeStr} 毫秒:{ms}");
if (!string.IsNullOrEmpty(timeStr) &&
DateTime.TryParseExact(timeStr, "yyyy-MM-dd HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out DateTime serverTime))
DateTime.TryParseExact(timeStr, "yyyy-MM-dd HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out DateTime t))
{
_serverTimeOffset = serverTime - DateTime.Now;
_isTimeSynced = true;
Debug.Log($"北京时间同步成功:{CurrentBeijingTime:yyyy-MM-dd HH:mm:ss},偏移量:{_serverTimeOffset.TotalSeconds:F1}s");
OnTimeSynced?.Invoke(CurrentBeijingTime);
yield break;
serverTime = t.AddMilliseconds(ms);
}
else
{
@@ -124,52 +127,46 @@ public class BeijingTimeManager : MonoSingleton<BeijingTimeManager>
}
else if (url.Contains("timeapi.io"))
{
string timeStr = json["dateTime"]?.ToString();
Debug.Log(timeStr);
if (!string.IsNullOrEmpty(timeStr))
{
DateTime serverTime = DateTime.Parse(timeStr);
_serverTimeOffset = serverTime - DateTime.Now;
_isTimeSynced = true;
Debug.Log($"北京时间同步成功:{CurrentBeijingTime:yyyy-MM-dd HH:mm:ss},偏移量:{_serverTimeOffset.TotalSeconds:F1}s");
OnTimeSynced?.Invoke(CurrentBeijingTime);
yield break;
serverTime = DateTime.Parse(timeStr);
}
}
else if (url.Contains("worldtimeapi"))
{
string timeStr = json["datetime"]?.ToString();
Debug.Log(timeStr);
if (!string.IsNullOrEmpty(timeStr))
{
DateTime serverTime = DateTimeOffset.Parse(timeStr)
serverTime = DateTimeOffset.Parse(timeStr)
.ToOffset(TimeSpan.FromHours(8))
.DateTime;
_serverTimeOffset = serverTime - DateTime.Now;
_isTimeSynced = true;
Debug.Log($"北京时间同步成功:{CurrentBeijingTime:yyyy-MM-dd HH:mm:ss},偏移量:{_serverTimeOffset.TotalSeconds:F1}s");
OnTimeSynced?.Invoke(CurrentBeijingTime);
yield break;
}
}
else if (url.Contains("suning"))
{
string timeStr = json["sysTime2"]?.ToString();
Debug.Log(timeStr);
if (!string.IsNullOrEmpty(timeStr))
{
DateTime serverTime = DateTime.ParseExact(timeStr, "yyyy-MM-dd HH:mm:ss", null);
_serverTimeOffset = serverTime - DateTime.Now;
_isTimeSynced = true;
Debug.Log($"北京时间同步成功:{CurrentBeijingTime:yyyy-MM-dd HH:mm:ss},偏移量:{_serverTimeOffset.TotalSeconds:F1}s");
OnTimeSynced?.Invoke(CurrentBeijingTime);
yield break;
serverTime = DateTime.ParseExact(timeStr, "yyyy-MM-dd HH:mm:ss", null);
}
}
if (serverTime.HasValue)
{
// RTT 补偿:服务器生成响应到客户端接收耗时约为 RTT/2(假设网络对称)
// 补偿后服务器时间 = 服务器响应时间 + RTT/2
TimeSpan rtt = requestEndTime - requestStartTime;
DateTime compensatedServerTime = serverTime.Value + TimeSpan.FromTicks(rtt.Ticks / 2);
_serverTimeOffset = compensatedServerTime - requestEndTime;
_isTimeSynced = true;
Debug.Log($"北京时间同步成功:{CurrentBeijingTime:yyyy-MM-dd HH:mm:ss.fff},偏移量:{_serverTimeOffset.TotalSeconds:F3}s,RTT:{rtt.TotalSeconds:F3}s");
OnTimeSynced?.Invoke(CurrentBeijingTime);
yield break;
}
}
catch (Exception e)
{
+2 -1
View File
@@ -908,7 +908,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 22400762, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3}
propertyPath: m_AnchoredPosition.y
value: -0.000022888184
value: -0.000011444092
objectReference: {fileID: 0}
- target: {fileID: 22426080, guid: 67117722a812a2e46ab8cb8eafbf5f5e, type: 3}
propertyPath: m_AnchorMax.x
@@ -6287,6 +6287,7 @@ MonoBehaviour:
spawnList: []
isCreateFish: 0
isFrozen: 0
debugSpawnFishNumber:
isResources: 0
--- !u!114 &2075409202
MonoBehaviour:
@@ -145,10 +145,6 @@ public class MonsterContral : MonoBehaviour
{
LoadHitEffect();
baseMmove = isMove;
// ⭐ isMove=true 的鱼初始放在屏幕外 (9999,9999,0),
// 等待 MoveUpdate 根据 moveTime 算出曲线位置后自然显示
if (isMove)
transform.position = new Vector3(9999, 9999, 0);
}
public async void LoadHitEffect()
{
@@ -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 旧客户端出鱼链路(已删除)
@@ -277,6 +277,7 @@ namespace Assets.MyGame.Scripts.Net
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<OnFishSpawnData>>(msg).arguments[0];
if (data == null) return;
EventCenter.Instance.EventTrigger<OnFishSpawnData>(ConstEventString.OnFishSpawn, data);
Debug.Log("出鱼:"+msg);
}
/// <summary>鱼列表刷新</summary>
@@ -113,7 +113,9 @@ public class FishResourcesData
if (mc != null)
mc.fishTypeID = id;
Pool.Instance.dic[id] = new PoolData(prefab, CreateFishManager.Instance.poolRoot.gameObject, id);
// ⭐ 统一用 Pool.Instance 的 poolObj 作为父节点(不再用 CreateFishManager.poolRoot),
// 这样 Pool.Clear() 销毁 poolObj 时能连带销毁所有 poolList_XXX 子节点,避免残留
Pool.Instance.dic[id] = new PoolData(prefab, Pool.Instance.EnsurePoolRoot(), id);
}
}, MergeMode.Intersection);
+44 -10
View File
@@ -453,7 +453,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.w
value: 1
value: 0.7071068
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.x
@@ -461,7 +461,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.y
value: 0
value: -0.7071068
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.z
@@ -473,7 +473,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
value: -90
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
@@ -782,16 +782,28 @@ MonoBehaviour:
m_EditorClassIdentifier:
beilv: 0
guid:
lastMoveLineId:
monsterData:
die_Score: 0
isDie: 0
fishTypeConfig:
fishNumber:
fishName:
fishBrief:
fishType: 0
fishScore: 0
killWeight: 0
pathList:
fishImage:
fishMultipleDesc:
moveLine:
bezierCurveData:
name:
start: {x: 0, y: 0}
controlPoints: []
end: {x: 0, y: 0}
moveTime: 0
moveSpeed: 0
skeleton: {fileID: 0}
isSpine: 1
fishTypeID: 0
@@ -810,8 +822,11 @@ MonoBehaviour:
yzID:
colliderList: []
lockPoint: {fileID: 0}
bingDongEffect: {fileID: 0}
rotationPY: 60
baseMmove: 0
isRotate: 0
isNot1: 0
ischild0: 0
depthOffset: 0
bossName:
@@ -825,6 +840,8 @@ MonoBehaviour:
isDieFish: 0
dieTime: 3
v3: {x: 0, y: 0, z: 0}
isLocalCoin: 0
killerSitPos: -1
--- !u!328 &796878678113666614
VideoPlayer:
m_ObjectHideFlags: 0
@@ -1406,15 +1423,15 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalScale.x
value: 5
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalScale.y
value: 5
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalScale.z
value: 5
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalPosition.x
@@ -1430,7 +1447,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.w
value: 0.7071068
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.x
@@ -1438,7 +1455,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.y
value: -0.7071068
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalRotation.z
@@ -1450,7 +1467,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: -90
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4702196601499589, guid: 15b70d8841f762f4fb07e654be129063, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
@@ -1596,19 +1613,31 @@ MonoBehaviour:
m_EditorClassIdentifier:
beilv: 0
guid:
lastMoveLineId:
monsterData:
die_Score: 0
isDie: 0
fishTypeConfig:
fishNumber:
fishName:
fishBrief:
fishType: 0
fishScore: 0
killWeight: 0
pathList:
fishImage:
fishMultipleDesc:
moveLine:
bezierCurveData:
name:
start: {x: 0, y: 0}
controlPoints: []
end: {x: 0, y: 0}
moveTime: 0
moveSpeed: 0
skeleton: {fileID: 0}
isSpine: 1
fishTypeID: 0
fishTypeID: 11043
currState: 0
HP: 5
effect_Die: {fileID: 0}
@@ -1624,8 +1653,11 @@ MonoBehaviour:
yzID:
colliderList: []
lockPoint: {fileID: 866509008212961257}
bingDongEffect: {fileID: 0}
rotationPY: 60
baseMmove: 0
isRotate: 0
isNot1: 0
ischild0: 0
depthOffset: 0
bossName:
@@ -1639,3 +1671,5 @@ MonoBehaviour:
isDieFish: 0
dieTime: 3
v3: {x: 0, y: 0, z: 0}
isLocalCoin: 0
killerSitPos: -1
@@ -5506,7 +5506,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 1709254077376921, guid: 1b4c638f59a7c2e4ba234d3dc9b370bf, type: 3}
propertyPath: m_Name
value: 7005_Timeline Variant
value: 7005_Variant
objectReference: {fileID: 0}
- target: {fileID: 1709254077376921, guid: 1b4c638f59a7c2e4ba234d3dc9b370bf, type: 3}
propertyPath: m_Layer
@@ -8289,25 +8289,37 @@ MonoBehaviour:
m_EditorClassIdentifier:
beilv: 0
guid:
lastMoveLineId:
monsterData:
die_Score: 0
isDie: 0
fishTypeConfig:
fishNumber:
fishName:
fishBrief:
fishType: 0
fishScore: 0
killWeight: 0
pathList:
fishImage:
fishMultipleDesc:
moveLine:
bezierCurveData:
name:
start: {x: 0, y: 0}
controlPoints: []
end: {x: 0, y: 0}
moveTime: 0
moveSpeed: 0
skeleton: {fileID: 0}
isSpine: 1
fishTypeID: 0
fishTypeID: 11039
currState: 0
HP: 5
effect_Die: {fileID: 0}
effect_DieAward: {fileID: 0}
currEffect_DieAward: {fileID: 0}
isMove: 1
isMove: 0
is3D: 0
forwordXYZ:
fishenum: 0
@@ -8315,7 +8327,12 @@ MonoBehaviour:
isyz: 0
yzID:
colliderList: []
lockPoint: {fileID: 0}
bingDongEffect: {fileID: 0}
rotationPY: 60
baseMmove: 0
isRotate: 0
isNot1: 0
ischild0: 0
depthOffset: 0
bossName:
@@ -8329,6 +8346,8 @@ MonoBehaviour:
isDieFish: 0
dieTime: 3
v3: {x: 0, y: 0, z: 0}
isLocalCoin: 0
killerSitPos: -1
--- !u!1 &4901745685099615617 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1565702696994528, guid: 1b4c638f59a7c2e4ba234d3dc9b370bf,
@@ -754,6 +754,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
await FishResourcesData.UnLoadFishAssetsData();
await AudioResourcesData.UnLoadAudioGame();
await MonsterMoveLine.UnLoadBezier();
// ⭐ 清空子弹池 + 特效池(鱼池已在 UnLoadFishAssetsData 内清理)
BulletPool.Instance.ClearAll();
EffectPool.Instance.ClearAll();
_resourcesUnloaded = true;
}
@@ -789,6 +792,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
CreateFishManager.Instance.ExitRoom();
CreateFishManager.Instance.isResources = false;
// ⭐ 清空子弹池 + 特效池(鱼池已在 UnLoadFishAssetsData 内清理)
BulletPool.Instance.ClearAll();
EffectPool.Instance.ClearAll();
JinDuTiao.SetProgress(0.9f);
// ⭐ 最后2秒留着(和加入游戏流程一致)
@@ -1599,6 +1605,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
return;
}
pos = fallback.position;
// ⭐ 修复:fallback 有效时也要激活图标(之前漏掉导致子锁定图标偶尔不显示)
if (!icon.activeSelf) icon.SetActive(true);
}
else
{
@@ -1657,6 +1665,16 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
Transform lockTr = ResolveLockTransform(target, out colliderIndex);
currSitData.SetLockTarget(target, lockTr);
SyncLock(new List<string> { target?.guid }, colliderIndex);
// ⭐ 切换目标的瞬间立即更新主锁定图标位置和显示,
// 避免切换那帧图标还停在旧位置或没显示出来
if (currSitData.lockFX != null && lockTr != null && lockTr.gameObject.activeInHierarchy)
{
if (!currSitData.lockFX.activeSelf) currSitData.lockFX.SetActive(true);
Vector3 p = lockTr.position;
p.z = Camera.main.transform.position.z + 1;
currSitData.lockFX.transform.position = p;
}
}
else
{
@@ -2434,7 +2452,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
entryGold = entryGold,
entryTime = Time.time,
currentLevelIndex = initIdx,
nextMultiplierCheckTime = Time.time + 2f,
// ⭐ 初始检查时间加随机偏移(0~3s),避免多个 bot 同时换炮倍
nextMultiplierCheckTime = Time.time + 2f + Random.Range(0f, 3f),
nextExitCheckTime = Time.time + 5f,
hasExited = false
};
@@ -2600,7 +2619,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
if (cfg == null || cfg.multiplier == null) return;
var mc = cfg.multiplier;
if (Time.time < state.nextMultiplierCheckTime) return;
state.nextMultiplierCheckTime = Time.time + mc.checkInterval;
// ⭐ 检查间隔加随机抖动(0.5~1.5 倍),避免多个 bot 同时换炮倍
state.nextMultiplierCheckTime = Time.time + mc.checkInterval * Random.Range(0.5f, 1.5f);
float ratio = state.GetGoldRatio(sit.goldNum);
int maxIdx = mc.maxLevelIndex < 0 ? GetPaoBeiCount() - 1 : mc.maxLevelIndex;
File diff suppressed because one or more lines are too long