This commit is contained in:
2026-09-06 19:49:25 +08:00
parent 0887d61c5e
commit c2279de46b
13 changed files with 643 additions and 121 deletions
@@ -86,6 +86,7 @@ using Assets.MyGame.Scripts.Net.API;
using Assets.MyGame.Scripts.Net.API.UserData_SubClass;
using Assets.MyGame.Scripts.Net.APIResponses.Enum;
using Assets.MyGame.Scripts.Net.WebResponses;
using Assets.Framework.Tool;
using DG.Tweening;
using Newtonsoft.Json;
using Spine.Unity;
@@ -326,6 +327,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
item.btn_TurretAdd.gameObject.SetActive(false);
if (item.btn_TurretMinus != null)
item.btn_TurretMinus.gameObject.SetActive(false);
// ⭐ 自动攻击开关与加减倍按钮一样:非本地座位隐藏
if (item.toggle_AutoAttack != null)
item.toggle_AutoAttack.gameObject.SetActive(false);
}
}
@@ -1496,9 +1500,6 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
_propListBuilt = true;
if (propConfigData == null || tmp_PropItem == null || obj_PropItemParent == null) return;
// ⭐ 模板是场景内对象时先隐藏(引用指向预制体资产时 scene 无效,不能 SetActive 以免改资产)
if (tmp_PropItem.scene.IsValid()) tmp_PropItem.SetActive(false);
for (int i = 0; i < propConfigData.props.Count; i++)
{
var cfg = propConfigData.props[i];
@@ -1513,7 +1514,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
}
/// <summary>
/// 点击一级道具:在 tmp_PropTwoPanel 内按配置展开二级子道具列表
/// 点击一级道具:清空后按配置的 propType 读取后端已拥有道具(user.props),
/// 动态展开到二级 tmp_PropTwoPanel(每次点击都重建,保证数量/种类最新)
/// </summary>
private void ShowPropTwo(PropItemData cfg)
{
@@ -1527,42 +1529,108 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
Destroy(child);
}
// ⚠ 注意:这里判断的是 tmp_PropTwoItem(不是 tmp_PropItem)
if (tmp_PropTwoItem.scene.IsValid()) tmp_PropTwoItem.SetActive(false);
foreach (var sub in cfg.subProps)
// ⭐ 读取后端道具:按一级道具配置的类型过滤(none = 显示全部),只显示 count > 0 的
var matched = new List<BaseProductCount>();
var props = GameManager.Instance.user?.props;
if (props != null)
{
foreach (var p in props)
{
if (p == null || p.count <= 0) continue;
if (cfg.propType != PropEnum.none && p.type != (int)cfg.propType) continue;
matched.Add(p);
}
}
// ⭐ 只有 1 个时不用弹二层,直接触发该道具的使用效果
if (matched.Count == 1)
{
UsePropEffect(matched[0]);
return;
}
foreach (var p in matched)
{
if (sub == null) continue;
var item = Instantiate(tmp_PropTwoItem, tmp_PropTwoItemParent.transform);
SetPropItemText(item, sub.name);
SetPropItemIcon(item, sub.icon);
var data = sub;
SetPropItemText(item, $"{p.name} x{p.count}");
SetPropItemIconUrl(item, p.imageUrl);
var data = p; // 闭包捕获当前项
var btn = GetPropItemButton(item);
if (btn != null) btn.onClick.AddListener(() => UsePropEffect(data));
}
// 该类型下没有已拥有道具时给出占位提示
if (matched.Count == 0)
{
var empty = Instantiate(tmp_PropTwoItem, tmp_PropTwoItemParent.transform);
SetPropItemText(empty, "暂无道具");
}
tmp_PropTwoPanel.SetActive(true);
}
/// <summary>
/// 点击二级子道具:按枚举 effectType 分发效果(未接入的类型统一提示)
/// 点击二级子道具:按后端道具类型(PropEnum)触发使用效果
/// (刮刮卡/大喇叭/召唤卡/VIP经验 有实际流程,装备与碎片类不支持在游戏内使用,给予提示)
/// </summary>
private void UsePropEffect(SubPropData sub)
private void UsePropEffect(BaseProductCount p)
{
if (sub == null) return;
switch (sub.effectType)
if (p == null) return;
switch ((PropEnum)p.type)
{
case PropEffectType.大喇叭:
case PropEnum.大喇叭:
if (obj_DaLaBaPanel != null) obj_DaLaBaPanel.SetActive(true);
break;
case PropEffectType.召唤卡:
case PropEnum.召唤卡:
OnClickZhanHuanKa();
break;
case PropEnum.刮刮卡:
// 与 btn_GuaGuaKa 同流程:打开刮刮卡面板
subUIManager.ShowAsync(UIPanel.GuaGuaKa);
break;
case PropEnum.VIP经验:
// 游戏内简化为一次使用1个(背包里支持滑条选数量)
var typeName = string.IsNullOrEmpty(p.name) ? PropEnum.VIP经验.ToString() : p.name;
UIManager.Instance.ShowTiShi($"确定使用1个{typeName}吗?", () =>
{
APIRequestList.UseVipExp(1, (result) =>
{
UIManager.Instance.ShowBoardError(string.IsNullOrEmpty(result) ? "使用成功" : result);
// 刷新用户数据,同步道具数量与VIP经验
APIRequestList.GetUser((user) =>
{
if (user != null)
GameManager.Instance.UpdataUserData(user);
});
});
});
break;
case PropEnum.改名卡:
UIManager.Instance.ShowBoardError("改名卡请到主界面背包中使用");
break;
default:
UIManager.Instance.ShowBoardError($"[{sub.effectType}] 效果暂未接入");
// 装备/碎片等道具没有游戏内使用流程
UIManager.Instance.ShowBoardError($"[{(PropEnum)p.type}] 暂不支持在游戏内使用");
break;
}
}
/// <summary>克隆项图标:按后端 imageUrl 下载(与背包面板同惯例,回调时判空防已销毁)</summary>
private void SetPropItemIconUrl(GameObject item, string imageUrl)
{
if (string.IsNullOrEmpty(imageUrl)) return;
var img = item.transform.childCount > 0 ? item.transform.GetChild(0).GetComponent<Image>() : null;
if (img == null) img = item.GetComponent<Image>();
if (img == null) img = item.GetComponentInChildren<Image>();
if (img == null) return;
WebTool.DownImage(APIManager.baseURL + imageUrl, (texture) =>
{
if (item == null || img == null) return;
if (texture != null)
img.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f);
});
}
/// <summary>克隆项文本:优先取 child0 的 TMP,再退回自身/子级查找(与表情列表同惯例)</summary>
private void SetPropItemText(GameObject item, string text)
{