1
This commit is contained in:
@@ -79,9 +79,18 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
public GameObject dieFXPrefab; // 基础死亡特效
|
||||
public GameObject dieFXPrefabAward; // 普通鱼金币奖励特效
|
||||
public GameObject dieFXPrefabAwardProp; // 道具效果
|
||||
public GameObject dieFXPrefabAwardTmp; // Boss 分数浮动文本
|
||||
public GameObject dieFXPrefabAwardTmp_AddScore;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// 道具掉落配置(掉落数据由服务端 RoomKillNotice.drop 下发,客户端只负责展示)
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
[Header("道具掉落(服务端驱动)")]
|
||||
[Tooltip("道具掉落预制体(挂 FishKillProp 脚本)。为空则不展示掉落特效")]
|
||||
public GameObject propDropPrefab;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// 生成系统运行时数据
|
||||
// ----------------------------------------------------------------
|
||||
@@ -2015,17 +2024,15 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
// ⭐ 掉落道具推送去重:服务端把"击杀爆奖"和"掉落道具"拆成两条 RoomKillNotice 下发,
|
||||
// 第二条与击杀消息同 fishId/killtime/gold,但只有 drop、没有 param。
|
||||
// Boss 鱼 DieFish 是延迟回收(字典未即时移除),第二条若按击杀再处理一次:
|
||||
// ① not-self 模式下 _pending[key] 被覆盖 → 前一个"爆奖中"BJEndUI 失去引用、永久残留在座位上;
|
||||
// ② 重复克隆爆奖特效、重复走 DieFish → 特效/音效/爆奖双份(两个 Event 实例各出一次 bjEndUI)。
|
||||
// 客户端目前没有掉落弹窗逻辑(见 RoomKillNotice.drop 注释),直接跳过;将来做掉落 UI 时在此处理。
|
||||
// 此条消息不走击杀流程(避免重复爆奖),只创建道具掉落特效并飞向击杀者座位。
|
||||
// ⚠️ 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} " +
|
||||
NetLog.Log($"[CreateFishManager] 掉落道具推送:fishId={killFish.fishId} " +
|
||||
$"prop={killFish.drop.propNumber}×{killFish.drop.count}");
|
||||
HandleDropProp(killFish);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2467,6 +2474,92 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
}
|
||||
#endregion
|
||||
|
||||
// ================================================================
|
||||
// 道具掉落(服务端驱动:RoomKillNotice.drop 下发掉落数据)
|
||||
// ================================================================
|
||||
|
||||
/// <summary>
|
||||
/// 处理服务端下发的道具掉落推送(RoomKillNotice.drop 不为空、param 为空的消息)。
|
||||
/// 与金币流程对称:EffectPool 取预制体→转 Canvas 坐标→InitProp 设置编号和座位终点→
|
||||
/// SetCoinCount→FlyToSeat 飞到座位回收。
|
||||
/// 道具图标按 /uploads/{propNumber}.png 从服务端下载(由 FishKillProp 内部完成)。
|
||||
/// </summary>
|
||||
private void HandleDropProp(RoomKillNotice killFish)
|
||||
{
|
||||
if (propDropPrefab == null || killFish.drop == null) return;
|
||||
if (string.IsNullOrEmpty(killFish.drop.propNumber)) return;
|
||||
if (currGameType == null) return;
|
||||
|
||||
// 找击杀者座位
|
||||
SitPosData sitData = null;
|
||||
foreach (var item in currGameType.list_Sits)
|
||||
{
|
||||
if (item.user == killFish.userId)
|
||||
{
|
||||
sitData = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sitData == null)
|
||||
{
|
||||
NetLog.Log($"[CreateFishManager] 掉落道具找不到座位:userId={killFish.userId}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 找鱼位置(鱼可能已回收,找不到就用座位位置兜底)
|
||||
Vector3 dropPos = sitData.transform.position;
|
||||
if (fishDatas_hashCodekey.TryGetValue(killFish.fishId, out var monster) && monster != null)
|
||||
dropPos = monster.transform.position;
|
||||
|
||||
// 创建道具特效(和金币一样 autoReturn=false,由 FlyToSeat 手动回池)
|
||||
var propObj = EffectPool.Instance.Get(
|
||||
propDropPrefab,
|
||||
dropPos, Quaternion.identity,
|
||||
currGameType.subPanelParent.parent,
|
||||
autoReturn: false);
|
||||
if (propObj == null) return;
|
||||
|
||||
// 坐标转换(和金币一致:世界坐标转 UI Canvas 坐标)
|
||||
try
|
||||
{
|
||||
propObj.GetComponent<RectTransform>().anchoredPosition =
|
||||
CoordinateTransformation.WorldPos_ToCanvas(dropPos, GetUiCanvas());
|
||||
}
|
||||
catch
|
||||
{
|
||||
propObj.transform.position = dropPos;
|
||||
}
|
||||
|
||||
// 初始化道具:编号、数量、起点、终点(座位)、玩家信息
|
||||
var fishKillProp = propObj.GetComponent<FishKillProp>();
|
||||
if (fishKillProp == null)
|
||||
{
|
||||
// 预制体没挂 FishKillProp 脚本 → 回收并退出
|
||||
EffectPool.Instance.Return(propObj);
|
||||
return;
|
||||
}
|
||||
|
||||
fishKillProp.InitProp(
|
||||
killFish.drop.propNumber,
|
||||
killFish.drop.count,
|
||||
dropPos,
|
||||
sitData.transform.position,
|
||||
killFish.userId,
|
||||
sitData.posID,
|
||||
null);
|
||||
fishKillProp.JiaFen = (audioID) =>
|
||||
{
|
||||
AudioManager.Instance.PlayerFX(audioID);
|
||||
// TODO: 道具拾取后的业务逻辑(如刷新背包、弹获得面板等)
|
||||
};
|
||||
fishKillProp.SetCoinCount();
|
||||
fishKillProp.FlyToSeat();
|
||||
|
||||
GameManager.LogFishFlow("DROP_PROP", killFish.fishId,
|
||||
$"prop={killFish.drop.propName}×{killFish.drop.count} 座位={sitData.posID} 击杀者={killFish.userId}",
|
||||
propObj.GetInstanceID());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user