133 lines
6.2 KiB
C#
133 lines
6.2 KiB
C#
using UnityEditor;
|
||
using UnityEngine;
|
||
using BaseGames.Core.Save;
|
||
using BaseGames.World.Map;
|
||
|
||
namespace BaseGames.Editor.Setup
|
||
{
|
||
/// <summary>
|
||
/// 一键创建项目所需的非事件频道 ScriptableObject 资产占位件。
|
||
/// 菜单:BaseGames → Setup → Create Project Assets
|
||
///
|
||
/// 包含:
|
||
/// · Assets/_Game/Data/Save/SaveSecurityConfig.asset — HMAC 密钥容器(Addressable "SaveSecurityConfig",运行时经 AssetLoader 加载)
|
||
/// · Assets/_Game/Data/World/Map/RegionRegistry.asset — 区域注册表(SaveSlotUI 用于查找背景图)
|
||
/// · Assets/_Game/Data/World/Map/MapDatabase.asset — 全局地图数据库
|
||
/// </summary>
|
||
public static class ProjectAssetSetup
|
||
{
|
||
[MenuItem("BaseGames/Setup/Create Project Assets")]
|
||
public static void CreateAll()
|
||
{
|
||
CreateSaveSecurityConfig();
|
||
CreateMapDatabase(); // 先于 RegionRegistry,使其能自动绑定 _mapDatabase
|
||
CreateRegionRegistry();
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
Debug.Log("[ProjectAssetSetup] 项目资产初始化完成。");
|
||
}
|
||
|
||
// ── SaveSecurityConfig ────────────────────────────────────────────────
|
||
|
||
private static void CreateSaveSecurityConfig()
|
||
{
|
||
// 统一走 Addressables,不放 Resources。资产置于 Data/Save,并标 Addressable 地址 "SaveSecurityConfig"。
|
||
const string folder = "Assets/_Game/Data/Save";
|
||
const string assetPath = folder + "/SaveSecurityConfig.asset";
|
||
|
||
EnsureFolder("Assets/_Game/Data", "Save");
|
||
|
||
if (AssetDatabase.LoadAssetAtPath<SaveSecurityConfig>(assetPath) == null)
|
||
{
|
||
var cfg = ScriptableObject.CreateInstance<SaveSecurityConfig>();
|
||
// HmacKey 留空:开发期游戏正常运行(使用兜底密钥);构建前由 CI/CD 注入。
|
||
AssetDatabase.CreateAsset(cfg, assetPath);
|
||
Debug.Log($"[ProjectAssetSetup] 已创建 {assetPath}(HmacKey 留空,构建前需注入)。");
|
||
}
|
||
else Debug.Log("[ProjectAssetSetup] SaveSecurityConfig 已存在。");
|
||
|
||
MarkAddressable(assetPath, "SaveSecurityConfig");
|
||
}
|
||
|
||
/// <summary>将资产标记为 Addressable(置于默认组),并设置地址。</summary>
|
||
private static void MarkAddressable(string assetPath, string address)
|
||
{
|
||
var settings = UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject.Settings;
|
||
if (settings == null)
|
||
{
|
||
Debug.LogWarning($"[ProjectAssetSetup] 无 Addressable 设置,无法标记 '{address}'。");
|
||
return;
|
||
}
|
||
string guid = AssetDatabase.AssetPathToGUID(assetPath);
|
||
var entry = settings.CreateOrMoveEntry(guid, settings.DefaultGroup);
|
||
entry.SetAddress(address);
|
||
}
|
||
|
||
// ── RegionRegistry ────────────────────────────────────────────────────
|
||
|
||
private static void CreateRegionRegistry()
|
||
{
|
||
const string folder = "Assets/_Game/Data/World/Map";
|
||
const string assetPath = folder + "/RegionRegistry.asset";
|
||
|
||
EnsureFolder("Assets/_Game/Data", "World");
|
||
EnsureFolder("Assets/_Game/Data/World", "Map");
|
||
|
||
var registry = AssetDatabase.LoadAssetAtPath<RegionRegistrySO>(assetPath);
|
||
bool created = false;
|
||
if (registry == null)
|
||
{
|
||
registry = ScriptableObject.CreateInstance<RegionRegistrySO>();
|
||
AssetDatabase.CreateAsset(registry, assetPath);
|
||
created = true;
|
||
}
|
||
|
||
// 自动绑定 _mapDatabase(CreateMapDatabase 已先行创建);幂等,已存在的也补绑
|
||
var mapDb = AssetDatabase.LoadAssetAtPath<BaseGames.World.Map.MapDatabaseSO>(folder + "/MapDatabase.asset");
|
||
if (mapDb != null)
|
||
{
|
||
var so = new SerializedObject(registry);
|
||
var prop = so.FindProperty("_mapDatabase");
|
||
if (prop != null && prop.objectReferenceValue != mapDb)
|
||
{
|
||
prop.objectReferenceValue = mapDb;
|
||
so.ApplyModifiedProperties();
|
||
EditorUtility.SetDirty(registry);
|
||
}
|
||
}
|
||
Debug.Log($"[ProjectAssetSetup] RegionRegistry {(created ? "已创建" : "已存在")},_mapDatabase {(mapDb != null ? "已绑定" : "未找到 MapDatabase")}。请在 Inspector 中将 _regions 数组填入所有 RegionDefinitionSO。");
|
||
}
|
||
|
||
// ── MapDatabase ───────────────────────────────────────────────────────
|
||
|
||
private static void CreateMapDatabase()
|
||
{
|
||
const string folder = "Assets/_Game/Data/World/Map";
|
||
const string assetPath = folder + "/MapDatabase.asset";
|
||
|
||
if (AssetDatabase.LoadAssetAtPath<BaseGames.World.Map.MapDatabaseSO>(assetPath) != null)
|
||
{
|
||
Debug.Log("[ProjectAssetSetup] MapDatabase 已存在,跳过。");
|
||
return;
|
||
}
|
||
|
||
EnsureFolder("Assets/_Game/Data", "World");
|
||
EnsureFolder("Assets/_Game/Data/World", "Map");
|
||
|
||
var db = ScriptableObject.CreateInstance<BaseGames.World.Map.MapDatabaseSO>();
|
||
AssetDatabase.CreateAsset(db, assetPath);
|
||
Debug.Log($"[ProjectAssetSetup] 已创建 {assetPath}。");
|
||
}
|
||
|
||
// ── 工具 ──────────────────────────────────────────────────────────────
|
||
|
||
private static void EnsureFolder(string parent, string newFolder)
|
||
{
|
||
string fullPath = parent + "/" + newFolder;
|
||
if (!AssetDatabase.IsValidFolder(fullPath))
|
||
AssetDatabase.CreateFolder(parent, newFolder);
|
||
}
|
||
}
|
||
}
|