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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ namespace Assets.MyGame.Scripts.Net
|
||||
dic_API[APIType.ActivityConfig_DiamondShopList] = "/api/ActivityConfig/diamondShopList";
|
||||
dic_API[APIType.ActivityConfig_GoldShopList] = "/api/ActivityConfig/goldShopList";
|
||||
dic_API[APIType.ActivityConfig_ReliefConfig] = "/api/ActivityConfig/reliefConfig";
|
||||
dic_API[APIType.ActivityConfig_SignConfigs] = "/api/ActivityConfig/signConfigs";
|
||||
dic_API[APIType.ActivityConfig_SignConfig] = "/api/ActivityConfig/signConfig";
|
||||
dic_API[APIType.Hall_GetSignStatus] = "/api/Hall/GetSignStatus";
|
||||
dic_API[APIType.ActivityConfig_RegisterConfig] = "/api/ActivityConfig/registerConfig";
|
||||
dic_API[APIType.ActivityConfig_BattleOrderConfig] = "/api/ActivityConfig/battleOrderConfig";
|
||||
dic_API[APIType.ActivityConfig_FishingReturnConfig] = "/api/ActivityConfig/fishingReturnConfig";
|
||||
|
||||
@@ -43,11 +43,11 @@ namespace Assets.MyGame.Scripts.Net
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取签到池配置(GET)
|
||||
/// 获取签到活动配置(GET /api/ActivityConfig/signConfig,响应 SignActivityConfig:isOpen/cannotInterrupt/days)
|
||||
/// </summary>
|
||||
public static void GetSignConfigs(Action<List<SignConfig>> callback)
|
||||
public static void GetSignConfig(Action<SignActivityConfig> callback)
|
||||
{
|
||||
APIManager.Response<List<SignConfig>>(APIType.ActivityConfig_SignConfigs, callback);
|
||||
APIManager.Response<SignActivityConfig>(APIType.ActivityConfig_SignConfig, callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -123,13 +123,21 @@ namespace Assets.MyGame.Scripts.Net
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 签到(GET)
|
||||
/// 参数:用户ID
|
||||
/// 返回:long(data为本次签到奖励的金币数,后端直接返回数字,不是SignInfo对象)
|
||||
/// 签到(GET /api/Hall/SignIn)
|
||||
/// 返回:SignRewardResult(day=第几天,gold/diamond/product=本次奖励,服务端已含VIP加成)
|
||||
/// </summary>
|
||||
public static void SignIn(Action<long> callback)
|
||||
public static void SignIn(Action<SignRewardResult> callback)
|
||||
{
|
||||
APIManager.Response<long>(APIType.Hall_SignIn, callback);
|
||||
APIManager.Response<SignRewardResult>(APIType.Hall_SignIn, callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取签到状态(GET /api/Hall/GetSignStatus)
|
||||
/// 返回:SignStatusResult(当前签到进度与可领取状态)
|
||||
/// </summary>
|
||||
public static void GetSignStatus(Action<SignStatusResult> callback)
|
||||
{
|
||||
APIManager.Response<SignStatusResult>(APIType.Hall_GetSignStatus, callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace Assets.MyGame.Scripts.Net.API
|
||||
public ReliefConfig reliefConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 签到池配置
|
||||
/// 签到活动配置
|
||||
/// </summary>
|
||||
public List<SignConfig> signConfigs;
|
||||
public SignActivityConfig signActivityConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 金币商城配置
|
||||
|
||||
@@ -1,22 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Assets.MyGame.Scripts.Net.API.GameConfig_SubClass
|
||||
{
|
||||
/// <summary>
|
||||
/// 签到奖励配置
|
||||
/// 签到活动配置(Swagger: SignActivityConfig,ActivityConfig.signActivityConfig)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SignActivityConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否开启
|
||||
/// </summary>
|
||||
public bool isOpen;
|
||||
|
||||
/// <summary>
|
||||
/// 不可中断:true=漏签不回退(按累计次数循环);false=可中断(漏签重置回第1天)
|
||||
/// </summary>
|
||||
public bool cannotInterrupt;
|
||||
|
||||
/// <summary>
|
||||
/// 7 天奖励配置(按 day 1~7)
|
||||
/// </summary>
|
||||
public List<SignConfig> days;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单日签到奖励配置(Swagger: SignConfig)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SignConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// 第几天(1~7)
|
||||
/// </summary>
|
||||
public int order;
|
||||
|
||||
/// <summary>
|
||||
/// 金币
|
||||
/// </summary>
|
||||
public long gold;
|
||||
public int day;
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
@@ -29,8 +47,8 @@ namespace Assets.MyGame.Scripts.Net.API.GameConfig_SubClass
|
||||
public string icon;
|
||||
|
||||
/// <summary>
|
||||
/// 概率
|
||||
/// 奖励列表(GiftConfig.type: 1=金币 2=钻石 3=道具)
|
||||
/// </summary>
|
||||
public double probability;
|
||||
public List<GiftConfig> giftList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,18 +85,6 @@ namespace Assets.MyGame.Scripts.Net.APIResponses
|
||||
public int addDiamond; // 本次增加钻石
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 签到响应
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SignInfo
|
||||
{
|
||||
public int day; // 第几天签到
|
||||
public bool isToday; // 今日是否已签到
|
||||
public long rewardGold; // 奖励金币(改用long防溢出)
|
||||
public long rewardDiamond;// 奖励钻石(改用long防溢出)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户信息(切换炮台、翅膀、战神)
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
|
||||
using Assets.MyGame.Scripts.Net.API.UserData_SubClass;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Assets.MyGame.Scripts.Net.APIResponses
|
||||
{
|
||||
/// <summary>
|
||||
/// 签到奖励结果(GET /api/Hall/SignIn 响应)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SignRewardResult
|
||||
{
|
||||
/// <summary>本次签到对应第几天(1~7)</summary>
|
||||
public int day;
|
||||
/// <summary>本次奖励金币</summary>
|
||||
public long gold;
|
||||
/// <summary>本次奖励钻石</summary>
|
||||
public int diamond;
|
||||
/// <summary>本次奖励道具列表</summary>
|
||||
public List<BaseProductCount> product;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 签到状态(GET /api/Hall/GetSignStatus 响应):当前签到进度与可领取状态
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SignStatusResult
|
||||
{
|
||||
/// <summary>签到活动是否开启</summary>
|
||||
public bool isOpen;
|
||||
/// <summary>不可中断:true=漏签不回退(按累计次数循环);false=可中断(漏签重置)</summary>
|
||||
public bool cannotInterrupt;
|
||||
/// <summary>当前周期已完成到第几天(0~7)</summary>
|
||||
public int signDay;
|
||||
/// <summary>今天签到对应的天数(已签=已签天数;未签=下一次目标天数)</summary>
|
||||
public int todayDay;
|
||||
/// <summary>今天是否已签到</summary>
|
||||
public bool isTodaySigned;
|
||||
/// <summary>7 天奖励配置</summary>
|
||||
public List<SignConfig> days;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f11d508fb63c9084ab3948ee61ea44a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -22,6 +22,11 @@ namespace Assets.MyGame.Scripts.Net.API.UserData_SubClass
|
||||
/// 签到时间
|
||||
/// </summary>
|
||||
public long signTime;
|
||||
|
||||
/// <summary>
|
||||
/// 当前已签到的周期天数(0=未开始,1~7)
|
||||
/// </summary>
|
||||
public int signDay;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,8 +31,11 @@ namespace Assets.MyGame.Scripts.Net
|
||||
/// <summary>救济金配置(GET)</summary>
|
||||
ActivityConfig_ReliefConfig,
|
||||
|
||||
/// <summary>签到池配置(GET)</summary>
|
||||
ActivityConfig_SignConfigs,
|
||||
/// <summary>签到活动配置(GET)</summary>
|
||||
ActivityConfig_SignConfig,
|
||||
|
||||
/// <summary>获取签到状态(GET)</summary>
|
||||
Hall_GetSignStatus,
|
||||
|
||||
/// <summary>注册配置(GET)</summary>
|
||||
ActivityConfig_RegisterConfig,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17115695c4c201946b804b772100142e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,137 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &8222732459988217625
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8802702133347106559}
|
||||
- component: {fileID: 2822715846151478221}
|
||||
m_Layer: 5
|
||||
m_Name: Prop
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8802702133347106559
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8222732459988217625}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.4, y: 0.4, z: 0.4}
|
||||
m_ConstrainProportionsScale: 1
|
||||
m_Children:
|
||||
- {fileID: 6250418086618249309}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 100, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &2822715846151478221
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8222732459988217625}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: dcf86da74e3bba947934891ba2a69902, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
tMP_CoinCount: {fileID: 0}
|
||||
gold: {fileID: 0}
|
||||
silver: {fileID: 0}
|
||||
endPoint: {x: 0, y: 0, z: 0}
|
||||
isBoss: 0
|
||||
isLocalCoin: 0
|
||||
coinCount: 0
|
||||
userID:
|
||||
sitID: 0
|
||||
startPoint: {x: 0, y: 0, z: 0}
|
||||
propIco: {fileID: 8869491853869306038}
|
||||
--- !u!1 &8236831357060171625
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6250418086618249309}
|
||||
- component: {fileID: 4330466387219907929}
|
||||
- component: {fileID: 8869491853869306038}
|
||||
m_Layer: 5
|
||||
m_Name: Coin
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &6250418086618249309
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8236831357060171625}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8802702133347106559}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 49.999985, y: -50}
|
||||
m_SizeDelta: {x: 80, y: 80}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4330466387219907929
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8236831357060171625}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &8869491853869306038
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8236831357060171625}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 0
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: 4f84a65ffddb6cc43a280cab2ed65ca2, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 742f2b00809071748adce9b6c5b9d1f7
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,92 @@
|
||||
using Assets.Framework.Tool;
|
||||
using Assets.MyGame.Scripts.Net;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// 鱼死亡掉落道具脚本(与 CoinScript 同级,均继承 BJBase)。
|
||||
/// 行为类似金币:原地掉落 → 飞向击杀者座位 → 回收。
|
||||
/// 掉落数据由服务端 RoomKillNotice.drop 下发(propNumber/propName/count),
|
||||
/// 道具图标按 /uploads/{propNumber}.png 从服务端下载。
|
||||
/// </summary>
|
||||
public class FishKillProp : BJBase
|
||||
{
|
||||
/// <summary>道具图标(Inspector 绑定)</summary>
|
||||
public Image propIco;
|
||||
|
||||
/// <summary>
|
||||
/// 重写基类方法:道具不显示金币数字,而是下载并设置道具图标。
|
||||
/// 和 CoinScript.SetCoinCount() 对称,供外部统一调用。
|
||||
/// </summary>
|
||||
public override void SetCoinCount()
|
||||
{
|
||||
// 修正 z 轴(和 CoinScript 一致,防止 UI 层级下 z 不为 0 导致被遮挡)
|
||||
var v3 = transform.position;
|
||||
v3.z = 0;
|
||||
transform.position = v3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化道具(扩展 BJBase.Init,增加道具编号)。
|
||||
/// 由 CreateFishManager 在收到服务端掉落推送时调用。
|
||||
/// </summary>
|
||||
/// <param name="propNumber">道具编号(用于下载图标 /uploads/编号.png)</param>
|
||||
/// <param name="propCount">掉落数量</param>
|
||||
/// <param name="startPoint">掉落起点(鱼死亡位置)</param>
|
||||
/// <param name="endPoint">飞行终点(击杀者座位位置)</param>
|
||||
/// <param name="userID">击杀者 ID</param>
|
||||
/// <param name="sitID">座位 ID</param>
|
||||
/// <param name="jobj">附加数据(透传,回调时原样返回)</param>
|
||||
public void InitProp(string propNumber, int propCount, Vector3 startPoint, Vector3 endPoint,
|
||||
string userID = "", int sitID = 999, object jobj = null)
|
||||
{
|
||||
this.startPoint = startPoint;
|
||||
// 复用基类 Init 设置通用字段(道具不涉及金币数量,coinCount 传 0)
|
||||
Init(0, endPoint, userID, sitID, jobj);
|
||||
|
||||
// 下载道具图标:固定格式 /uploads/{propNumber}.png
|
||||
DownloadPropIcon(propNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从服务端下载道具图标并设置到 propIco。
|
||||
/// 失败时 propIco 保留预制体上配置好的默认图(不强制兜底重试)。
|
||||
/// </summary>
|
||||
private void DownloadPropIcon(string propNumber)
|
||||
{
|
||||
if (string.IsNullOrEmpty(propNumber) || propIco == null) return;
|
||||
|
||||
string url = APIManager.baseURL + "/uploads/" + propNumber + ".png";
|
||||
WebTool.DownImage(url, tex =>
|
||||
{
|
||||
// 回调时本物体可能已被销毁(飞到座位后回池/切场景),需判空
|
||||
if (this == null || propIco == null) return;
|
||||
if (tex != null)
|
||||
{
|
||||
propIco.sprite = Sprite.Create(tex,
|
||||
new Rect(0, 0, tex.width, tex.height),
|
||||
Vector2.one * 0.5f);
|
||||
propIco.SetNativeSize();
|
||||
propIco.gameObject.SetActive(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 飞到座位位置并回收(效果同 coinEvent.HuiShou)。
|
||||
/// 可由动画事件调用(预制体有掉落动画时),也可直接调用实现原地掉落后立即飞向座位。
|
||||
/// </summary>
|
||||
public void FlyToSeat()
|
||||
{
|
||||
transform.DOMove(endPoint, 0.5f).OnComplete(() =>
|
||||
{
|
||||
// 拾取回调(由 CreateFishManager 设置 JiaFen)
|
||||
JiaFen?.Invoke(0);
|
||||
// 拾取音效(复用金币拾取音效)
|
||||
AudioManager.Instance.PlayerFX(61009);
|
||||
// 池化回收
|
||||
EffectPool.Instance.Return(gameObject);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcf86da74e3bba947934891ba2a69902
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -61420,7 +61420,7 @@ PrefabInstance:
|
||||
- target: {fileID: 6597416787623719195, guid: 0627c90518880634a948686e845a5161,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6597416787623719195, guid: 0627c90518880634a948686e845a5161,
|
||||
type: 3}
|
||||
@@ -61430,7 +61430,7 @@ PrefabInstance:
|
||||
- target: {fileID: 6597416787623719195, guid: 0627c90518880634a948686e845a5161,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMin.y
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6597416787623719195, guid: 0627c90518880634a948686e845a5161,
|
||||
type: 3}
|
||||
@@ -61480,12 +61480,12 @@ PrefabInstance:
|
||||
- target: {fileID: 6597416787623719195, guid: 0627c90518880634a948686e845a5161,
|
||||
type: 3}
|
||||
propertyPath: m_AnchoredPosition.x
|
||||
value: 0
|
||||
value: 1140.2
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6597416787623719195, guid: 0627c90518880634a948686e845a5161,
|
||||
type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: 0
|
||||
value: -366.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6597416787623719195, guid: 0627c90518880634a948686e845a5161,
|
||||
type: 3}
|
||||
@@ -62533,7 +62533,7 @@ PrefabInstance:
|
||||
- target: {fileID: 3618039173474018553, guid: 76edf10e1a3669a4cbe017114b08c6a2,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3618039173474018553, guid: 76edf10e1a3669a4cbe017114b08c6a2,
|
||||
type: 3}
|
||||
@@ -62543,7 +62543,7 @@ PrefabInstance:
|
||||
- target: {fileID: 3618039173474018553, guid: 76edf10e1a3669a4cbe017114b08c6a2,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMin.y
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3618039173474018553, guid: 76edf10e1a3669a4cbe017114b08c6a2,
|
||||
type: 3}
|
||||
@@ -62593,12 +62593,12 @@ PrefabInstance:
|
||||
- target: {fileID: 3618039173474018553, guid: 76edf10e1a3669a4cbe017114b08c6a2,
|
||||
type: 3}
|
||||
propertyPath: m_AnchoredPosition.x
|
||||
value: 0
|
||||
value: 242
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3618039173474018553, guid: 76edf10e1a3669a4cbe017114b08c6a2,
|
||||
type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: 0
|
||||
value: -366.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3618039173474018553, guid: 76edf10e1a3669a4cbe017114b08c6a2,
|
||||
type: 3}
|
||||
@@ -63329,7 +63329,7 @@ PrefabInstance:
|
||||
- target: {fileID: 2455563011306354547, guid: f3b4b23ca2531734fa3699e11040b988,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2455563011306354547, guid: f3b4b23ca2531734fa3699e11040b988,
|
||||
type: 3}
|
||||
@@ -63339,7 +63339,7 @@ PrefabInstance:
|
||||
- target: {fileID: 2455563011306354547, guid: f3b4b23ca2531734fa3699e11040b988,
|
||||
type: 3}
|
||||
propertyPath: m_AnchorMin.y
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2455563011306354547, guid: f3b4b23ca2531734fa3699e11040b988,
|
||||
type: 3}
|
||||
@@ -63389,12 +63389,12 @@ PrefabInstance:
|
||||
- target: {fileID: 2455563011306354547, guid: f3b4b23ca2531734fa3699e11040b988,
|
||||
type: 3}
|
||||
propertyPath: m_AnchoredPosition.x
|
||||
value: 0
|
||||
value: 691.1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2455563011306354547, guid: f3b4b23ca2531734fa3699e11040b988,
|
||||
type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: 0
|
||||
value: -366.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2455563011306354547, guid: f3b4b23ca2531734fa3699e11040b988,
|
||||
type: 3}
|
||||
|
||||
@@ -11,10 +11,9 @@ using UnityEngine.UI;
|
||||
|
||||
public class UIHome_BY_UISignViewPanel : SubUIBase
|
||||
{
|
||||
//text_CoinNums是转盘各个位置的详细值 他从GameManager的activityConfig里面读取signConfigs后端配置的个数和text_CoinNums的个数是对应的 这里赋值的时候需要加上其他的数据公式是 值+值*GameManager的gameConfig的vip的signInAdd签到加成
|
||||
//text_CoinNums是转盘各个位置的详细值 他从GameManager的activityConfig里面读取signActivityConfig.days后端配置的个数和text_CoinNums的个数是对应的 这里赋值的时候需要加上其他的数据公式是 值+值*GameManager的gameConfig的vip的signInAdd签到加成
|
||||
/*签到API已封装在APIRequestList.SignIn(GET)
|
||||
实测后端返回 {"data":440,"code":0,"info":null}——data直接是本次奖励的金币数字(不是SignInfo对象)
|
||||
转盘停靠位置用奖励金额反查signConfigs得到(见FindSlotByReward)*/
|
||||
响应为SignRewardResult:{day, gold, diamond, product}——day=本次签到天数(1~7),转盘直接按day停靠格子(不再金额反查)*/
|
||||
//SLZPDieEvent这个脚本有之前写好的多层转盘的逻辑 签到这里只有单层 你可以直接看一下里面正确的
|
||||
public List<Text> text_CoinNums;
|
||||
public List<TextMeshProUGUI> text_CoinNums_TMP;
|
||||
@@ -23,7 +22,7 @@ public class UIHome_BY_UISignViewPanel : SubUIBase
|
||||
public TextMeshProUGUI tmp_EndCoin; // 显示最终奖励金币数
|
||||
public Button btn_ChouJiang;
|
||||
public GameObject zhuanPan;
|
||||
Dictionary<int, SignConfig> order_singConfig;
|
||||
Dictionary<int, SignConfig> day_singConfig; // key=第几天(1~7)
|
||||
|
||||
[Header("转盘参数(参照SLZPDieEvent)")]
|
||||
public int spinRounds = 5; // 到达目标前转的圈数
|
||||
@@ -47,7 +46,7 @@ public class UIHome_BY_UISignViewPanel : SubUIBase
|
||||
|
||||
private void RefreshPanel()
|
||||
{
|
||||
BuildOrderSignConfig();
|
||||
BuildDaySignConfig();
|
||||
UpdateSlotTexts();
|
||||
UpdateBtnState();
|
||||
UpdateVipAddText();
|
||||
@@ -61,16 +60,16 @@ public class UIHome_BY_UISignViewPanel : SubUIBase
|
||||
tmp_VipJiaCheng.text = $"+{add * 100:0}%";
|
||||
}
|
||||
|
||||
/// <summary>从GameManager的activityConfig读取signConfigs,按order建立字典</summary>
|
||||
private void BuildOrderSignConfig()
|
||||
/// <summary>从GameManager的activityConfig读取signActivityConfig.days,按day建立字典</summary>
|
||||
private void BuildDaySignConfig()
|
||||
{
|
||||
order_singConfig = new Dictionary<int, SignConfig>();
|
||||
var signConfigs = GameManager.Instance.activityConfig?.signConfigs;
|
||||
if (signConfigs == null) return;
|
||||
foreach (var cfg in signConfigs)
|
||||
day_singConfig = new Dictionary<int, SignConfig>();
|
||||
var days = GameManager.Instance.activityConfig?.signActivityConfig?.days;
|
||||
if (days == null) return;
|
||||
foreach (var cfg in days)
|
||||
{
|
||||
if (cfg == null) continue;
|
||||
order_singConfig[cfg.order] = cfg;
|
||||
day_singConfig[cfg.day] = cfg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,25 +100,33 @@ public class UIHome_BY_UISignViewPanel : SubUIBase
|
||||
text_CoinNums_TMP[index].text = value;
|
||||
}
|
||||
|
||||
/// <summary>转盘格子赋值:值+值*signInAdd(VIP签到加成),按order排序后与text_CoinNums一一对应</summary>
|
||||
/// <summary>转盘格子赋值:金币值+值*signInAdd(VIP签到加成),按day排序后与text_CoinNums一一对应</summary>
|
||||
private void UpdateSlotTexts()
|
||||
{
|
||||
int slotCount = SlotCount();
|
||||
if (order_singConfig == null || order_singConfig.Count == 0 || slotCount == 0) return;
|
||||
if (day_singConfig == null || day_singConfig.Count == 0 || slotCount == 0) return;
|
||||
|
||||
var list = new List<SignConfig>(order_singConfig.Values);
|
||||
list.Sort((a, b) => a.order - b.order);
|
||||
var list = new List<SignConfig>(day_singConfig.Values);
|
||||
list.Sort((a, b) => a.day - b.day);
|
||||
|
||||
double add = GetSignInAdd();
|
||||
int count = Mathf.Min(list.Count, slotCount);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
long gold = list[i].gold;
|
||||
long gold = GetGiftGold(list[i]);
|
||||
long showGold = gold + (long)Math.Round(gold * add);
|
||||
SetSlotText(i, FormatGold(showGold));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>取单日配置中的金币奖励数(giftList 中 type=1 金币项;无金币项返回0)</summary>
|
||||
private static long GetGiftGold(SignConfig cfg)
|
||||
{
|
||||
if (cfg?.giftList == null) return 0;
|
||||
var goldGift = cfg.giftList.Find(g => g != null && g.type == 1);
|
||||
return goldGift != null ? goldGift.count : 0;
|
||||
}
|
||||
|
||||
/// <summary>今日是否已签到</summary>
|
||||
private bool IsSignedToday()
|
||||
{
|
||||
@@ -137,19 +144,24 @@ public class UIHome_BY_UISignViewPanel : SubUIBase
|
||||
if (isSpinning) return;
|
||||
btn_ChouJiang.interactable = false;
|
||||
|
||||
// 后端SignIn的data直接返回本次奖励的金币数(数字)
|
||||
APIRequestList.SignIn(reward =>
|
||||
// SignIn 返回 SignRewardResult:day=本次签到天数,gold/diamond/product=本次奖励(服务端已含VIP加成)
|
||||
APIRequestList.SignIn(res =>
|
||||
{
|
||||
int slot = FindSlotByReward(reward);
|
||||
if (slot < 0)
|
||||
if (res == null)
|
||||
{
|
||||
// 奖励金额匹配不到任何格子:不转转盘直接提示,避免停错位置
|
||||
Debug.LogWarning($"[签到] 奖励{reward}在signConfigs里匹配不到对应格子");
|
||||
OnSignInDone(reward);
|
||||
OnSignInDone(0);
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[签到] 奖励{reward} → 转盘格子{slot}");
|
||||
RotateToSlot(slot, () => OnSignInDone(reward));
|
||||
int slot = SlotIndexByDay(res.day);
|
||||
if (slot < 0)
|
||||
{
|
||||
// day 匹配不到格子:不转转盘直接提示,避免停错位置
|
||||
Debug.LogWarning($"[签到] 第{res.day}天在签到配置里匹配不到对应格子");
|
||||
OnSignInDone(res.gold);
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[签到] 第{res.day}天奖励{res.gold}金币 → 转盘格子{slot}");
|
||||
RotateToSlot(slot, () => OnSignInDone(res.gold));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -168,25 +180,20 @@ public class UIHome_BY_UISignViewPanel : SubUIBase
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>按奖励金额反查转盘格子:优先匹配加了VIP加成后的值,其次匹配原始配置值;匹配不到返回-1</summary>
|
||||
private int FindSlotByReward(long reward)
|
||||
/// <summary>按签到天数定位转盘格子:days按day升序后的下标;匹配不到返回-1</summary>
|
||||
private int SlotIndexByDay(int day)
|
||||
{
|
||||
if (order_singConfig == null || order_singConfig.Count == 0 || SlotCount() == 0) return -1;
|
||||
if (day_singConfig == null || day_singConfig.Count == 0 || SlotCount() == 0) return -1;
|
||||
|
||||
var list = new List<SignConfig>(order_singConfig.Values);
|
||||
list.Sort((a, b) => a.order - b.order);
|
||||
var list = new List<SignConfig>(day_singConfig.Values);
|
||||
list.Sort((a, b) => a.day - b.day);
|
||||
|
||||
double add = GetSignInAdd();
|
||||
int count = Mathf.Min(list.Count, SlotCount());
|
||||
int fallback = -1;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
long gold = list[i].gold;
|
||||
long withAdd = gold + (long)Math.Round(gold * add);
|
||||
if (withAdd == reward) return i;
|
||||
if (fallback < 0 && gold == reward) fallback = i;
|
||||
if (list[i].day == day) return i;
|
||||
}
|
||||
return fallback;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>单层转盘旋转停靠(参照SLZPDieEvent:LocalAxisAdd增量旋转+OutCubic缓动+完成强制校正)</summary>
|
||||
|
||||
Reference in New Issue
Block a user