1
This commit is contained in:
@@ -155,15 +155,17 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
public Button btn_ChangeRoom;
|
||||
|
||||
[Header("表情包")]
|
||||
[Tooltip("表情包配置资产(一份配置多场景共用;未拖时回退下方面板旧字段)")]
|
||||
public BiaoQingConfig biaoQingConfig;
|
||||
public Button btn_BiaoQing; // 打开/关闭表情面板
|
||||
public GameObject obj_BiaoQingPanel; // 表情面板(开/关)
|
||||
public GameObject obj_BiaoQingZiItemPrefab; // 文字表情项预制体(child0=TextMeshProUGUI)
|
||||
public GameObject obj_BiaoQingSpineItemPrefab; // spine表情项预制体(child0=SkeletonGraphic)
|
||||
public GameObject obj_BiaoQingSpineItemParent; // spine表情项生成的父节点
|
||||
public GameObject obj_BiaoQingZiItemParent; // 文字表情项生成的父节点
|
||||
[Tooltip("spine 表情配置:每个元素=一个spine文件+动画名列表,按动画名逐个克隆成表情项")]
|
||||
[Tooltip("(回退用)spine 表情配置:优先读 biaoQingConfig 资产,未拖资产时才用这里")]
|
||||
public List<BiaoQingSpineData> list_BiaoQingSpine = new List<BiaoQingSpineData>();
|
||||
[Tooltip("文字表情内容列表,一条文字克隆一个表情项")]
|
||||
[Tooltip("(回退用)文字表情内容列表:优先读 biaoQingConfig 资产,未拖资产时才用这里")]
|
||||
public List<string> list_BiaoQingZi = new List<string>();
|
||||
|
||||
|
||||
@@ -600,7 +602,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
bool open = !obj_PropPanel.activeSelf;
|
||||
obj_PropPanel.SetActive(open);
|
||||
if (open)
|
||||
{
|
||||
BuildPropList();
|
||||
// ⭐ 数量是动态数据:每次打开面板都刷新一级角标(构建有一次性守卫,刷新无守卫)
|
||||
RefreshPropFirstLayerCounts();
|
||||
}
|
||||
else if (tmp_PropTwoPanel != null)
|
||||
tmp_PropTwoPanel.SetActive(false);
|
||||
});
|
||||
@@ -1274,6 +1280,14 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
#region 表情包(BiaoQingModule:列表生成 + 发送 + 广播接收)
|
||||
|
||||
/// <summary>spine 表情列表:优先读 biaoQingConfig 配置资产(多场景共用一份),未拖资产时回退面板字段</summary>
|
||||
private List<BiaoQingSpineData> BiaoQingSpineList =>
|
||||
biaoQingConfig != null ? biaoQingConfig.list_BiaoQingSpine : list_BiaoQingSpine;
|
||||
|
||||
/// <summary>文字表情列表:优先读 biaoQingConfig 配置资产(多场景共用一份),未拖资产时回退面板字段</summary>
|
||||
private List<string> BiaoQingZiList =>
|
||||
biaoQingConfig != null ? biaoQingConfig.list_BiaoQingZi : list_BiaoQingZi;
|
||||
|
||||
/// <summary>表情列表是否已生成(首次打开面板时生成一次)</summary>
|
||||
private bool _biaoQingListBuilt = false;
|
||||
|
||||
@@ -1293,9 +1307,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
/// <summary>
|
||||
/// 生成表情列表(只生成一次),两种形式分开处理:
|
||||
/// ① spine 表情:遍历 list_BiaoQingSpine,每个配置里的每个动画名克隆一个 spine 项
|
||||
/// ① spine 表情:遍历 BiaoQingSpineList(优先 biaoQingConfig 资产),每个配置里的每个动画名克隆一个 spine 项
|
||||
/// (child0=SkeletonGraphic → 换骨骼资源 + 循环播放该动画做列表预览);
|
||||
/// ② 文字表情:list_BiaoQingZi 每条文字克隆一个文字项(child0=TextMeshProUGUI → 设置文字)。
|
||||
/// ② 文字表情:BiaoQingZiList 每条文字克隆一个文字项(child0=TextMeshProUGUI → 设置文字)。
|
||||
/// </summary>
|
||||
private void BuildBiaoQingList()
|
||||
{
|
||||
@@ -1305,9 +1319,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
// ---- ① spine 表情:一个动画名 = 一项 ----
|
||||
if (obj_BiaoQingSpineItemPrefab != null && obj_BiaoQingSpineItemParent != null)
|
||||
{
|
||||
for (int i = 0; i < list_BiaoQingSpine.Count; i++)
|
||||
for (int i = 0; i < BiaoQingSpineList.Count; i++)
|
||||
{
|
||||
var cfg = list_BiaoQingSpine[i];
|
||||
var cfg = BiaoQingSpineList[i];
|
||||
if (cfg == null || cfg.skeletonDataAsset == null) continue;
|
||||
|
||||
foreach (var animName in cfg.animationNames)
|
||||
@@ -1338,7 +1352,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
// ---- ② 文字表情:一条文字 = 一项 ----
|
||||
if (obj_BiaoQingZiItemPrefab != null && obj_BiaoQingZiItemParent != null)
|
||||
{
|
||||
foreach (var text in list_BiaoQingZi)
|
||||
foreach (var text in BiaoQingZiList)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text)) continue;
|
||||
|
||||
@@ -1404,9 +1418,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
if (type == BiaoQingType.spine)
|
||||
{
|
||||
// spineIndex = list_BiaoQingSpine 配置下标 → 取骨骼资源交给座位显示
|
||||
var cfg = (spineIndex >= 0 && spineIndex < list_BiaoQingSpine.Count)
|
||||
? list_BiaoQingSpine[spineIndex]
|
||||
// spineIndex = 表情配置列表下标(biaoQingConfig 资产)→ 取骨骼资源交给座位显示
|
||||
var cfg = (spineIndex >= 0 && spineIndex < BiaoQingSpineList.Count)
|
||||
? BiaoQingSpineList[spineIndex]
|
||||
: null;
|
||||
if (cfg == null || cfg.skeletonDataAsset == null) return;
|
||||
sit.ShowBiaoQingSpine(cfg.skeletonDataAsset, content);
|
||||
@@ -1491,6 +1505,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
private bool _propListBuilt;
|
||||
|
||||
/// <summary>已构建的一级道具项映射(cfg → 克隆项),供数量角标刷新用</summary>
|
||||
private readonly List<KeyValuePair<PropItemData, GameObject>> _propFirstLayerItems = new List<KeyValuePair<PropItemData, GameObject>>();
|
||||
|
||||
/// <summary>
|
||||
/// 按 PropConfigData 构建一级道具列表(只在首次打开时构建一次)
|
||||
/// </summary>
|
||||
@@ -1505,12 +1522,42 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
var cfg = propConfigData.props[i];
|
||||
if (cfg == null) continue;
|
||||
var item = Instantiate(tmp_PropItem, obj_PropItemParent.transform);
|
||||
SetPropItemText(item, cfg.name);
|
||||
// ⭐ 第一层 child0 = 数量 TMP(只显示数字,不显示名字,靠图标辨识)
|
||||
SetPropItemIcon(item, cfg.icon);
|
||||
var data = cfg; // 闭包捕获当前项,避免循环变量被覆盖
|
||||
var btn = GetPropItemButton(item);
|
||||
if (btn != null) btn.onClick.AddListener(() => ShowPropTwo(data));
|
||||
_propFirstLayerItems.Add(new KeyValuePair<PropItemData, GameObject>(cfg, item));
|
||||
}
|
||||
RefreshPropFirstLayerCounts();
|
||||
}
|
||||
|
||||
/// <summary>刷新一级道具 child0 数量:仅当该类型下只有 1 个已拥有道具(点击直接使用、不弹二层)时显示个数;
|
||||
/// 可以打开二层的一级项(0 个显示"暂无道具"占位 / 多个展开子道具列表)直接显示空</summary>
|
||||
private void RefreshPropFirstLayerCounts()
|
||||
{
|
||||
foreach (var kv in _propFirstLayerItems)
|
||||
{
|
||||
if (kv.Value == null) continue; // 克隆项已被销毁
|
||||
var matched = GetMatchedProps(kv.Key != null ? kv.Key.propType : PropEnum.none);
|
||||
// ⭐ 只有 1 个已拥有道具(点击直达使用)才显示个数;能弹二层的显示空
|
||||
SetPropItemTextAt(kv.Value, 0, matched.Count == 1 ? matched[0].count.ToString() : string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>按类型读取后端已拥有道具(none = 全部类型),只取 count > 0 的(一级角标与二级展开共用同一过滤规则)</summary>
|
||||
private List<BaseProductCount> GetMatchedProps(PropEnum type)
|
||||
{
|
||||
var matched = new List<BaseProductCount>();
|
||||
var props = GameManager.Instance.user?.props;
|
||||
if (props == null) return matched;
|
||||
foreach (var p in props)
|
||||
{
|
||||
if (p == null || p.count <= 0) continue;
|
||||
if (type != PropEnum.none && p.type != (int)type) continue;
|
||||
matched.Add(p);
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1530,17 +1577,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
}
|
||||
|
||||
// ⭐ 读取后端道具:按一级道具配置的类型过滤(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);
|
||||
}
|
||||
}
|
||||
// (与一级角标 RefreshPropFirstLayerCounts 共用 GetMatchedProps,规则一致)
|
||||
var matched = GetMatchedProps(cfg.propType);
|
||||
|
||||
// ⭐ 只有 1 个时不用弹二层,直接触发该道具的使用效果
|
||||
if (matched.Count == 1)
|
||||
@@ -1552,7 +1590,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
foreach (var p in matched)
|
||||
{
|
||||
var item = Instantiate(tmp_PropTwoItem, tmp_PropTwoItemParent.transform);
|
||||
SetPropItemText(item, $"{p.name} x{p.count}");
|
||||
// ⭐ child0 = 名字,child1 = 数量(tmp_PropTwoItem 的 child1 是数量 TMP)
|
||||
SetPropItemText(item, p.name);
|
||||
SetPropItemTextAt(item, 1, p.count.ToString());
|
||||
SetPropItemIconUrl(item, p.imageUrl);
|
||||
var data = p; // 闭包捕获当前项
|
||||
var btn = GetPropItemButton(item);
|
||||
@@ -1601,6 +1641,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
{
|
||||
if (user != null)
|
||||
GameManager.Instance.UpdataUserData(user);
|
||||
RefreshPropFirstLayerCounts(); // 数量变化后同步刷新一级角标
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1641,6 +1682,15 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
if (tmp != null) tmp.text = text;
|
||||
}
|
||||
|
||||
/// <summary>克隆项固定子节点文本:按索引取 child{childIndex} 的 TMP(如第一层child0数量、第二层child1数量)</summary>
|
||||
private void SetPropItemTextAt(GameObject item, int childIndex, string text)
|
||||
{
|
||||
var tmp = item.transform.childCount > childIndex
|
||||
? item.transform.GetChild(childIndex).GetComponent<TextMeshProUGUI>()
|
||||
: null;
|
||||
if (tmp != null) tmp.text = text;
|
||||
}
|
||||
|
||||
/// <summary>克隆项图标:优先取 child0 的 Image,再退回自身/子级查找(icon 不填则跳过)</summary>
|
||||
private void SetPropItemIcon(GameObject item, Sprite icon)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user