using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using BaseGames.UI;
using BaseGames.UI.Theme;
using BaseGames.Core.Events;
using BaseGames.Localization;
using BaseGames.Editor.Localization;
namespace BaseGames.Editor.UI
{
///
/// 图鉴脚手架:生成 UI_BestiaryCell + UI_BestiaryPanel 预制件 + 空 UI_BestiaryDatabase 表 + BESTIARY_* 中英文案。
/// 面板据 BestiaryDatabaseSO 列出全部敌人,经 IBestiaryService 读已发现态(已发现亮/未发现 ??? + 剪影 + 锁),
/// 订阅 EVT_BestiaryUpdated 实时刷新;点击格子在右侧详情区展示。
///
/// 数据:策划在 UI_BestiaryDatabase 增删条目(enemyId 须与 EnemyBase._enemyId 一致),或用「同步图鉴条目」工具自动补。
/// 菜单:BaseGames/UI/控件库/生成图鉴(预制件 + 空表)
///
public static class UIBestiaryScaffold
{
private const string PrefabDir = "Assets/_Game/Prefabs/UI";
private const string ControlsDir = "Assets/_Game/Prefabs/UI/Controls";
private const string ConfigDir = "Assets/_Game/Data/UI";
private const string ThemePath = "Assets/_Game/Data/UI/Themes/UI_Theme_Default.asset";
private const string PanelName = "UI_BestiaryPanel";
private const string CellName = "UI_BestiaryCell";
private const string DbName = "UI_BestiaryDatabase";
[MenuItem("BaseGames/UI/控件库/生成图鉴(预制件 + 空表)")]
public static void GeneratePrefab()
{
EnsureFolder(PrefabDir); EnsureFolder(ControlsDir); EnsureFolder(ConfigDir);
var report = new List();
var theme = AssetDatabase.LoadAssetAtPath(ThemePath);
var db = EnsureDatabase(report);
SeedLocalization(report);
var cell = BuildCellPrefab(theme, report);
BuildPanelPrefab(theme, db, cell, report);
AssetDatabase.SaveAssets(); AssetDatabase.Refresh();
var sb = new System.Text.StringBuilder("[UIBestiary] 图鉴已生成:\n");
foreach (var r in report) sb.AppendLine(" • " + r);
sb.AppendLine("策划在 UI_BestiaryDatabase 填敌人条目(enemyId 同 EnemyBase._enemyId);重跑「Scaffold Inventory Hub」收编为图鉴 Tab。");
Debug.Log(sb.ToString());
}
private static BestiaryDatabaseSO EnsureDatabase(List report)
{
string path = $"{ConfigDir}/{DbName}.asset";
var db = AssetDatabase.LoadAssetAtPath(path);
if (db == null)
{
db = ScriptableObject.CreateInstance();
AssetDatabase.CreateAsset(db, path);
report.Add($"{path}(空表,待策划/同步工具填充)");
}
return db;
}
private static void SeedLocalization(List report)
{
var zh = new Dictionary
{
{ "MENU_BESTIARY", "图鉴" }, { "BESTIARY_TITLE", "图鉴" },
{ "BESTIARY_LOCKED", "???" }, { "BESTIARY_LOCKED_DESC", "尚未发现该敌人。" },
{ "BESTIARY_HP", "生命" }, { "BESTIARY_KILLS", "击杀" },
};
var en = new Dictionary
{
{ "MENU_BESTIARY", "Bestiary" }, { "BESTIARY_TITLE", "Bestiary" },
{ "BESTIARY_LOCKED", "???" }, { "BESTIARY_LOCKED_DESC", "Not yet discovered." },
{ "BESTIARY_HP", "HP" }, { "BESTIARY_KILLS", "Kills" },
};
int added = MergeWriteUI(Language.ChineseSimplified, zh) + MergeWriteUI(Language.English, en);
report.Add($"本地化新增 {added} 条(已存在不覆盖)。");
}
private static int MergeWriteUI(Language lang, Dictionary kv)
{
var dict = LocalizationFileIO.Read(lang, LocalizationTable.UI);
int added = 0;
foreach (var p in kv) if (!dict.ContainsKey(p.Key)) { dict[p.Key] = p.Value; added++; }
if (added > 0) LocalizationFileIO.Write(lang, LocalizationTable.UI, dict);
return added;
}
// ── 单元格预制件 ─────────────────────────────────────────────────────
private static BestiaryCellView BuildCellPrefab(UIThemeSO theme, List report)
{
var root = new GameObject(CellName, typeof(RectTransform), typeof(CanvasGroup));
((RectTransform)root.transform).sizeDelta = new Vector2(170f, 130f);
var view = root.AddComponent();
var bg = root.AddComponent();
bg.sprite = Std(); bg.type = Image.Type.Sliced; bg.color = new Color(1f, 1f, 1f, 0.05f);
var btn = root.AddComponent