Files
zeling_v2/Assets/_Game/Scripts/Editor/Setup/ProjectAssetSetup.cs
2026-06-05 18:41:33 +08:00

133 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
// 自动绑定 _mapDatabaseCreateMapDatabase 已先行创建);幂等,已存在的也补绑
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);
}
}
}