1
This commit is contained in:
Binary file not shown.
@@ -218,6 +218,22 @@ MonoBehaviour:
|
||||
m_bufferingTime: 0.1
|
||||
m_ClipProperties:
|
||||
volume: 0.172
|
||||
--- !u!114 &-8174235504841704556
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 15c38f6fa1940124db1ab7f6fe7268d1, type: 3}
|
||||
m_Name: Signal Emitter
|
||||
m_EditorClassIdentifier:
|
||||
m_Time: 10.066666666666666
|
||||
m_Retroactive: 0
|
||||
m_EmitOnce: 0
|
||||
m_Asset: {fileID: 11400000, guid: 1508e534c5cd88d459d245dd3557a1c6, type: 2}
|
||||
--- !u!114 &-8072677713721982766
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
@@ -1079,6 +1095,7 @@ MonoBehaviour:
|
||||
m_Markers:
|
||||
m_Objects:
|
||||
- {fileID: 6527845954037689115}
|
||||
- {fileID: -8174235504841704556}
|
||||
--- !u!114 &-4838957258320222283
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
|
||||
@@ -19,6 +19,7 @@ using Assets.MyGame.Scripts.Net.APIResponses.GameConfig_SubClass;
|
||||
using Assets.MyGame.Scripts.Net.WebResponses;
|
||||
using cfg;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -173,6 +174,16 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <summary>特殊 Boss</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_TS_Boss = new Dictionary<string, MonsterContral>();
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// 击杀消息幂等去重(fishId|killtime → 处理时刻)
|
||||
// 服务端可能对同一次击杀下发多条 RoomKillNotice(掉落推送之外的重复/重发),
|
||||
// 同 fishId+killtime 只处理第一条,防止重复克隆爆奖特效/重复出 bjEndUI;
|
||||
// MultiDeath(星际巡航等多次死亡玩法)每段 killtime 不同,不受影响。
|
||||
// ----------------------------------------------------------------
|
||||
private readonly Dictionary<string, float> _handledKillKeys = new Dictionary<string, float>();
|
||||
private readonly List<string> _expiredKillKeys = new List<string>();
|
||||
private const float KillDedupKeepSeconds = 60f; // 键保鲜期(秒),超时清理防字典增长
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// ⭐ 编辑器调试 List:与上方字典同步,方便在 Inspector 查看当前场上活鱼
|
||||
public List<MonsterContral> fishList_All = new List<MonsterContral>();
|
||||
@@ -1961,15 +1972,40 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// 第二条与击杀消息同 fishId/killtime/gold,但只有 drop、没有 param。
|
||||
// Boss 鱼 DieFish 是延迟回收(字典未即时移除),第二条若按击杀再处理一次:
|
||||
// ① not-self 模式下 _pending[key] 被覆盖 → 前一个"爆奖中"BJEndUI 失去引用、永久残留在座位上;
|
||||
// ② 重复克隆爆奖特效、重复走 DieFish → 特效/音效/爆奖双份。
|
||||
// ② 重复克隆爆奖特效、重复走 DieFish → 特效/音效/爆奖双份(两个 Event 实例各出一次 bjEndUI)。
|
||||
// 客户端目前没有掉落弹窗逻辑(见 RoomKillNotice.drop 注释),直接跳过;将来做掉落 UI 时在此处理。
|
||||
if (killFish.drop != null && killFish.param == null)
|
||||
// ⚠️ param 是 JToken:JSON "param":null 会被反序列化成 JValue(Null)(Type==JTokenType.Null),
|
||||
// 不能只判 C# null(与 BossKillParam.cs 的判空写法保持一致),否则第二条漏拦 → 重复爆奖。
|
||||
if (killFish.drop != null
|
||||
&& (killFish.param == null || killFish.param.Type == JTokenType.Null))
|
||||
{
|
||||
NetLog.Log($"[CreateFishManager] 掉落道具推送(跳过击杀处理):fishId={killFish.fishId} " +
|
||||
$"prop={killFish.drop.propNumber}×{killFish.drop.count}");
|
||||
return;
|
||||
}
|
||||
|
||||
// ⭐ 击杀消息幂等去重(第二道锁):同 fishId+killtime+beishu+gold 已处理过 → 判为同一次击杀的
|
||||
// 重复/重发消息,直接跳过,防止重复走击杀流程(重复克隆爆奖特效 → 两个 Event 实例各出一次
|
||||
// bjEndUI = 重复显示爆奖标志)。
|
||||
// ⚠️ 掉落推送(param 为空)已在上面被拦、不会记录键,避免"掉落先到"时误挡真正的击杀消息;
|
||||
// MultiDeath(星际巡航等多次死亡玩法)同一秒内多段的 killtime 可能相同,但各段 beishu/gold
|
||||
// 不同,键里带上二者后正常放行。
|
||||
string killKey = killFish.fishId + "|" + killFish.killtime + "|" + killFish.beishu + "|" + killFish.gold;
|
||||
if (_handledKillKeys.ContainsKey(killKey))
|
||||
{
|
||||
NetLog.Log($"[CreateFishManager] 重复击杀消息(跳过):key={killKey}");
|
||||
return;
|
||||
}
|
||||
_handledKillKeys[killKey] = Time.unscaledTime;
|
||||
if (_handledKillKeys.Count >= 64) // 顺手清理过期键,防字典增长
|
||||
{
|
||||
float nowTime = Time.unscaledTime;
|
||||
_expiredKillKeys.Clear();
|
||||
foreach (var kv in _handledKillKeys)
|
||||
if (nowTime - kv.Value > KillDedupKeepSeconds) _expiredKillKeys.Add(kv.Key);
|
||||
foreach (var k in _expiredKillKeys) _handledKillKeys.Remove(k);
|
||||
}
|
||||
|
||||
NetLog.Log($"[CreateFishManager] 杀鱼延迟:{DateTimeOffset.Now.ToUnixTimeSeconds() - killFish.timespan}s");
|
||||
SitPosData sitData = null; //击杀玩家座位数据
|
||||
foreach (var item in currGameType.list_Sits)
|
||||
|
||||
@@ -79,6 +79,16 @@ public class FLZY_JL_Boss : MonsterControl_BossBase
|
||||
base.DieFish(obj);
|
||||
animator.speed = 0;
|
||||
GetComponent<Animator>().enabled = true;
|
||||
|
||||
// ⭐ 他人击杀(含机器人)时立即回池:
|
||||
// 金龙/青龙不像其他 Boss(PTS/GSL 等)在 DieFish 里直接 Id_DieFish_NotFX,
|
||||
// 而是靠 FLZY_BOSS_AnimatorLeave 的动画状态退出回调回池;但上面 animator.speed=0
|
||||
// 把状态机冻住后,状态永远走不到 Exit → 回调永不触发 →
|
||||
// 第二个玩家视角里死龙会一直冻在屏幕中央,整个"爆奖中"期间乃至结束后都不消失。
|
||||
// 自己击杀保持原表现(尸体定格当爆奖背景,与自己流程已验收的效果一致)。
|
||||
if (!isLocalCoin)
|
||||
CreateFishManager.Instance.Id_DieFish_NotFX(guid);
|
||||
|
||||
action_effect_DieAward = (o) =>
|
||||
{
|
||||
if (obj == null) return;
|
||||
|
||||
@@ -138,7 +138,9 @@ public class JinLongEvent : BJRedPacketEvent
|
||||
// 全部完成
|
||||
tMP_Score.text = maxScore.ToString();
|
||||
isAddScore = false;
|
||||
JiaFen?.Invoke();
|
||||
// ⭐ 不在这里直接调 JiaFen:1.5 秒后 OnScoreEnd(基类统一收尾)里会调一次,
|
||||
// 这里多调一次会导致击杀者座位金币加两遍、baoJiangEnd 帧同步连发两条
|
||||
// (日志已证实:同 fishId 收到两条 baoJiangEnd)。
|
||||
Invoke(nameof(die), 1f);
|
||||
Invoke(nameof(OnScoreEnd), 1.5f);
|
||||
}
|
||||
|
||||
@@ -1094,7 +1094,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &8926196532408561376
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1111,9 +1111,9 @@ RectTransform:
|
||||
- {fileID: 5724427392508043228}
|
||||
m_Father: {fileID: 38992651813133378}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 86, y: -60}
|
||||
m_SizeDelta: {x: 68, y: 62}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4112040777350681982
|
||||
@@ -4320,7 +4320,7 @@ MonoBehaviour:
|
||||
list_BiaoQingZi: []
|
||||
mySitAnim: {fileID: 448370382151683116}
|
||||
mySitAnimOffsetLeft: {x: 70, y: 0, z: 0}
|
||||
mySitAnimOffsetRight: {x: -70, y: 0, z: 0}
|
||||
mySitAnimOffsetRight: {x: 55, y: 0, z: 0}
|
||||
toggle_Lock: {fileID: 1095565694137767186}
|
||||
toggle_Three: {fileID: 557993769889242771}
|
||||
toggle_Shuang: {fileID: 6788830007509759241}
|
||||
@@ -4377,6 +4377,9 @@ MonoBehaviour:
|
||||
goldColumnOffsetX: 80
|
||||
goldColumnDeltaX: 40
|
||||
goldColumnOffsetY: 0
|
||||
goldColumnOffsetXRight: 200
|
||||
goldColumnDeltaXRight: 40
|
||||
goldColumnOffsetYRight: 0
|
||||
btn_NukeList: {fileID: 8750404718084592857}
|
||||
nukeListPanel: {fileID: 8718899482206626550}
|
||||
nukeItemTemplate: {fileID: 8717863517958971103}
|
||||
@@ -4432,6 +4435,9 @@ MonoBehaviour:
|
||||
deltaX: 0
|
||||
offsetX: 0
|
||||
offsetY: 0
|
||||
deltaXRight: 40
|
||||
offsetXRight: 100
|
||||
offsetYRight: 0
|
||||
heightCap: 255
|
||||
scoreDivisor: 2
|
||||
barHeightToPanelRatio: 0.47
|
||||
@@ -12532,7 +12538,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 0}
|
||||
m_AnchoredPosition: {x: -388, y: 59.886642}
|
||||
m_AnchoredPosition: {x: -463.33, y: 59.886642}
|
||||
m_SizeDelta: {x: 812.1321, y: 186.42029}
|
||||
m_Pivot: {x: 0.4217527, y: 0.32124478}
|
||||
--- !u!114 &7267664368300524434
|
||||
@@ -17279,7 +17285,7 @@ PrefabInstance:
|
||||
- target: {fileID: 224349892793438657, guid: 6f077aa14d1a8e34687a3af5f0f1eae5,
|
||||
type: 3}
|
||||
propertyPath: m_SizeDelta.x
|
||||
value: 6
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 224349892793438657, guid: 6f077aa14d1a8e34687a3af5f0f1eae5,
|
||||
type: 3}
|
||||
@@ -17309,7 +17315,7 @@ PrefabInstance:
|
||||
- target: {fileID: 224448299783411175, guid: 6f077aa14d1a8e34687a3af5f0f1eae5,
|
||||
type: 3}
|
||||
propertyPath: m_SizeDelta.x
|
||||
value: 6
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 224448299783411175, guid: 6f077aa14d1a8e34687a3af5f0f1eae5,
|
||||
type: 3}
|
||||
|
||||
@@ -59,13 +59,19 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
|
||||
public GoldColumnController goldColumnController;
|
||||
private GoldColumnController _goldColumn;
|
||||
|
||||
[Header("金币柱位置(面板上实时调,每次出柱生效)")]
|
||||
[Tooltip("首柱相对座位的 X 偏移(以此处为准,控制器组件上的同名字段会被覆盖)")]
|
||||
[Header("金币柱位置(面板上实时调,每次出柱生效;左右座位各一套)")]
|
||||
[Tooltip("左座位:首柱相对座位的 X 偏移(以此处为准,控制器组件上的同名字段会被覆盖)")]
|
||||
public float goldColumnOffsetX = 150f;
|
||||
[Tooltip("相邻金币柱的 X 间距")]
|
||||
[Tooltip("左座位:相邻金币柱的 X 间距")]
|
||||
public float goldColumnDeltaX = 40f;
|
||||
[Tooltip("金币柱 Y(相对面板底边,0=贴着底边往上长)")]
|
||||
[Tooltip("左座位:金币柱 Y(相对面板底边,0=贴着底边往上长)")]
|
||||
public float goldColumnOffsetY = 0f;
|
||||
[Tooltip("右座位:首柱相对座位的 X 偏移(左/右按座位在面板中线的左/右判定)")]
|
||||
public float goldColumnOffsetXRight = 150f;
|
||||
[Tooltip("右座位:相邻金币柱的 X 间距")]
|
||||
public float goldColumnDeltaXRight = 40f;
|
||||
[Tooltip("右座位:金币柱 Y(相对面板底边,0=贴着底边往上长)")]
|
||||
public float goldColumnOffsetYRight = 0f;
|
||||
|
||||
// ==================== 核弹列表(按钮 + 缩放面板) ====================
|
||||
[Header("核弹列表(按钮 + 缩放面板)")]
|
||||
@@ -495,9 +501,13 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
|
||||
}
|
||||
|
||||
// ⭐ 位置参数以面板上的字段为准(每次出柱前同步,Play 模式下改完立即生效)
|
||||
// 左右座位各一套:控制器内按座位在面板中线的左/右(sign)自动选对应那组
|
||||
_goldColumn.offsetX = goldColumnOffsetX;
|
||||
_goldColumn.deltaX = goldColumnDeltaX;
|
||||
_goldColumn.offsetY = goldColumnOffsetY;
|
||||
_goldColumn.offsetXRight = goldColumnOffsetXRight;
|
||||
_goldColumn.deltaXRight = goldColumnDeltaXRight;
|
||||
_goldColumn.offsetYRight = goldColumnOffsetYRight;
|
||||
|
||||
bool isSelf = currSitData != null && sit == currSitData;
|
||||
_goldColumn.ShowOne(sit, earn, isSelf);
|
||||
|
||||
@@ -27,11 +27,15 @@ public class GoldColumnController : MonoBehaviour
|
||||
public int maxColumns = 5;
|
||||
[Tooltip("队伍长度超过此值时,队头不再额外停顿(快速滚动)")]
|
||||
public int crowdThreshold = 3;
|
||||
// ⚠️ 这三个位置参数由面板脚本 GameMainPanel_XJMH 每帧同步(goldColumnOffsetX/DeltaX/OffsetY),
|
||||
// 请在面板的 GameMainPanel_XJMH 组件上调,不要在这里调(这里改了会被覆盖)。
|
||||
// ⚠️ 这六个位置参数由面板脚本 GameMainPanel_XJMH 每次出柱前同步
|
||||
// (无后缀=左座位、Right=右座位),请在面板的 GameMainPanel_XJMH 组件上调,不要在这里调(这里改了会被覆盖)。
|
||||
// 左右判定:座位在面板中线左侧(sign<0)用无后缀那组,右侧(sign>0)用 Right 那组。
|
||||
[HideInInspector] public float deltaX = 40f;
|
||||
[HideInInspector] public float offsetX = 100f;
|
||||
[HideInInspector] public float offsetY = 0f;
|
||||
[HideInInspector] public float deltaXRight = 40f;
|
||||
[HideInInspector] public float offsetXRight = 100f;
|
||||
[HideInInspector] public float offsetYRight = 0f;
|
||||
|
||||
[Header("高度映射(沿用 PW 公式)")]
|
||||
[Tooltip("高度封顶值:score/scoreDivisor 达到此值即顶格")]
|
||||
@@ -243,8 +247,12 @@ public class GoldColumnController : MonoBehaviour
|
||||
SetNum(item, ChangeUnit(pending.earn));
|
||||
|
||||
// 位置:X = 座位位置 + 方向 × (首柱外偏 + 序号间距);Y = offsetY(0=贴面板底边,柱子往上长)
|
||||
float x = pending.basePos.x + pending.sign * (offsetX + item.index * deltaX);
|
||||
float y = offsetY;
|
||||
// ⭐ 左右座位各一套偏移:sign<0=座位在面板左 → 无后缀那组;sign>0=右 → Right 那组
|
||||
float offX = pending.sign < 0f ? offsetX : offsetXRight;
|
||||
float dltX = pending.sign < 0f ? deltaX : deltaXRight;
|
||||
float offY = pending.sign < 0f ? offsetY : offsetYRight;
|
||||
float x = pending.basePos.x + pending.sign * (offX + item.index * dltX);
|
||||
float y = offY;
|
||||
item.rt.anchoredPosition = new Vector2(x, y);
|
||||
|
||||
// 高度:默认沿用 PW 公式 score=earn/炮倍 → mul=score/scoreDivisor → 封顶归一化;
|
||||
@@ -324,7 +332,10 @@ public class GoldColumnController : MonoBehaviour
|
||||
{
|
||||
var item = list[i];
|
||||
item.index = i;
|
||||
float targetX = item.basePos.x + item.sign * (offsetX + i * deltaX);
|
||||
// ⭐ 与 SpawnOne 同规则:按该柱所在座位的左/右(sign)选对应偏移
|
||||
float offX = item.sign < 0f ? offsetX : offsetXRight;
|
||||
float dltX = item.sign < 0f ? deltaX : deltaXRight;
|
||||
float targetX = item.basePos.x + item.sign * (offX + i * dltX);
|
||||
item.moveTween?.Kill();
|
||||
item.moveTween = item.rt.DOAnchorPosX(targetX, shiftDuration).SetEase(Ease.Linear);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user