Compare commits
2 Commits
c88d2d0549
...
82ce9ff09a
| Author | SHA1 | Date | |
|---|---|---|---|
| 82ce9ff09a | |||
| 442d4c9cfc |
@@ -34,7 +34,7 @@ namespace BaseGames.Editor
|
||||
private static readonly Color ColMissing = new Color(0.95f, 0.55f, 0.10f, 0.80f); // 无效 Key(不在 Addressables)
|
||||
private static readonly Color ColOk = new Color(0.20f, 0.75f, 0.30f, 0.80f); // 正常
|
||||
|
||||
[MenuItem("BaseGames/Tools/Asset Reference Graph")]
|
||||
[MenuItem("BaseGames/Addressables/Asset Reference Graph")]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
var win = GetWindow<AddressReferenceGraphWindow>("Asset Reference Graph");
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace BaseGames.Editor
|
||||
{
|
||||
// ── 常量 ─────────────────────────────────────────────────────────────
|
||||
private const string Title = "Addressable 批量工具";
|
||||
private const string MenuPath = "BaseGames/Tools/Addressable Batch Tool";
|
||||
private const string MenuPath = "BaseGames/Addressables/Addressable Batch Tool";
|
||||
private const string PrefsKey = "AddressableBatch.";
|
||||
|
||||
// ── 状态 ─────────────────────────────────────────────────────────────
|
||||
@@ -77,7 +77,7 @@ namespace BaseGames.Editor
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────
|
||||
[MenuItem(MenuPath, priority = 200)]
|
||||
[MenuItem("BaseGames/Verification/Open Addressable Batch Tool", priority = 250)]
|
||||
[MenuItem("BaseGames/Addressables/Open Addressable Batch Tool", priority = 250)]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
var win = GetWindow<AddressableBatchTool>(Title);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0547dd5099c322248a3a2652f4b01cc9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 195ffa39c13090d4e94d81ab10b6c721
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -42,7 +42,7 @@ namespace BaseGames.Editor
|
||||
private readonly Dictionary<int, SerializedObject> _soCache = new Dictionary<int, SerializedObject>();
|
||||
// ══ 菜单入口 ══════════════════════════════════════════════════════════
|
||||
|
||||
[MenuItem("BaseGames/Camera/Camera Area Setup", priority = 100)]
|
||||
[MenuItem("BaseGames/Scene/Camera Area Setup", priority = 100)]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
var win = GetWindow<CameraAreaSetupTool>("Camera Area Setup");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07ed02361aa3739468cbd36457aecda6
|
||||
guid: c58b8b4e1f9da6a42ac3d362d4bf4014
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -38,7 +38,7 @@ namespace BaseGames.Editor
|
||||
private static StyleSheet Uss =>
|
||||
_uss != null ? _uss : (_uss = AssetDatabase.LoadAssetAtPath<StyleSheet>(UssPath));
|
||||
|
||||
[MenuItem("BaseGames/Tools/Character Wizard", priority = 1)]
|
||||
[MenuItem("BaseGames/Data/Character Wizard", priority = 1)]
|
||||
public static void Open()
|
||||
{
|
||||
var wnd = GetWindow<CharacterWizardWindow>();
|
||||
@@ -39,7 +39,7 @@ namespace BaseGames.Editor
|
||||
private static readonly Color ColDelay = new Color(0.25f, 0.25f, 0.30f, 0.50f);
|
||||
private static readonly Color ColWarn = new Color(0.95f, 0.10f, 0.10f, 0.85f);
|
||||
|
||||
[MenuItem("BaseGames/Tools/Boss Skill Sequence Viewer")]
|
||||
[MenuItem("BaseGames/Data/Boss Skill Sequence", priority = 110)]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
var win = GetWindow<BossSkillSequenceWindow>("Boss Skill Sequence");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 763f62796f2f4ed43a21dfe3befb70a1
|
||||
guid: f8e429c47dfa7fe4da6d9687c02398ea
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -18,7 +18,7 @@ namespace BaseGames.Editor
|
||||
private static readonly PropertyInfo s_bakeJobProp =
|
||||
typeof(NavSurface).GetProperty("BakeJob", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
[MenuItem("BaseGames/Tools/Bake All NavSurfaces %#b", priority = 100)]
|
||||
[MenuItem("BaseGames/Scene/Bake All NavSurfaces %#b", priority = 100)]
|
||||
public static void BakeAll()
|
||||
{
|
||||
var surfaces = Object.FindObjectsByType<NavSurface>(FindObjectsSortMode.None);
|
||||
@@ -42,7 +42,7 @@ namespace BaseGames.Editor
|
||||
Debug.Log($"[NavSurfaceBake] 开始烘焙 {count} 个 NavSurface……");
|
||||
}
|
||||
|
||||
[MenuItem("BaseGames/Tools/Bake All NavSurfaces %#b", validate = true)]
|
||||
[MenuItem("BaseGames/Scene/Bake All NavSurfaces %#b", validate = true)]
|
||||
private static bool BakeAllValidate()
|
||||
{
|
||||
// 仅在非 Play Mode 时可用(NavSurface.Bake 仅支持编辑器模式)
|
||||
@@ -35,7 +35,7 @@ namespace BaseGames.Editor
|
||||
private static readonly Color ColActive = new Color(0.95f, 0.60f, 0.10f, 0.80f);
|
||||
private static readonly Color ColPending = new Color(0.70f, 0.70f, 0.75f, 0.80f);
|
||||
|
||||
[MenuItem("BaseGames/Tools/Event Chain Viewer")]
|
||||
[MenuItem("BaseGames/Events/Event Chain Viewer")]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
var win = GetWindow<EventChainEditorWindow>("Event Chain Viewer");
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace BaseGames.Editor
|
||||
{
|
||||
private const string RootPath = "Assets/_Game/Data/Events";
|
||||
|
||||
[MenuItem("BaseGames/Tools/Create Event Channel Assets")]
|
||||
[MenuItem("BaseGames/Events/Create Event Channels")]
|
||||
public static void CreateAll()
|
||||
{
|
||||
// ── Core 原始类型频道 ──────────────────────────────────────────────
|
||||
@@ -115,7 +115,7 @@ namespace BaseGames.Editor
|
||||
Debug.Log("[CreateEventChannelAssets] 所有事件频道资产生成完毕。");
|
||||
}
|
||||
|
||||
[MenuItem("BaseGames/Tools/Reimport Event Channel Assets")]
|
||||
[MenuItem("BaseGames/Events/Reimport Event Channels")]
|
||||
public static void ReimportAllEventAssets()
|
||||
{
|
||||
if (!AssetDatabase.IsValidFolder(RootPath))
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace BaseGames.Editor
|
||||
private bool _autoScroll = true;
|
||||
private Vector2 _scroll;
|
||||
|
||||
[MenuItem("BaseGames/Tools/Event Bus Monitor %#e")]
|
||||
[MenuItem("BaseGames/Events/Event Bus Monitor %#e")]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
EventBusMonitorWindow window = GetWindow<EventBusMonitorWindow>("Event Bus Monitor");
|
||||
|
||||
8
Assets/_Game/Scripts/Editor/Player.meta
Normal file
8
Assets/_Game/Scripts/Editor/Player.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89f2177f5a1c33044a6c38a2633f0ade
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/_Game/Scripts/Editor/Progression.meta
Normal file
8
Assets/_Game/Scripts/Editor/Progression.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 172d69bd8cc35c34197a1974bd9cc9c3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -51,7 +51,7 @@ namespace BaseGames.Editor
|
||||
|
||||
// ── 菜单入口 ──────────────────────────────────────────────────────────
|
||||
|
||||
[MenuItem("BaseGames/Tools/Boot Flow Wizard", priority = 10)]
|
||||
[MenuItem("BaseGames/Scene/Setup/Boot Flow Wizard", priority = 10)]
|
||||
public static void Open()
|
||||
{
|
||||
var wnd = GetWindow<BootFlowSetupWizard>();
|
||||
|
||||
@@ -15,13 +15,13 @@ namespace BaseGames.Editor
|
||||
/// 运行时(Play Mode / 发行版 Build)的保证由 GameBootstrap(Runtime 程序集)负责,
|
||||
/// 本脚本与 Play Mode 状态无关,不监听 playModeStateChanged。
|
||||
///
|
||||
/// 菜单:BaseGames/Tools/Edit Mode: Auto-Open Persistent Scene
|
||||
/// 菜单:BaseGames/Scene/Setup/Auto-Open Persistent Scene
|
||||
/// </summary>
|
||||
[InitializeOnLoad]
|
||||
public static class PersistentSceneAutoLoader
|
||||
{
|
||||
// ── 常量 ─────────────────────────────────────────────────────────────
|
||||
private const string MenuPath = "BaseGames/Tools/Edit Mode: Auto-Open Persistent Scene";
|
||||
private const string MenuPath = "BaseGames/Scene/Setup/Auto-Open Persistent Scene";
|
||||
private const string PrefKey = "BaseGames_EditAutoOpen_Persistent";
|
||||
private const string PersistentSceneName = "Scene_Persistent";
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace BaseGames.Editor
|
||||
public static class SceneScaffoldTools
|
||||
{
|
||||
|
||||
[MenuItem("BaseGames/Tools/Scaffold Persistent Scene")]
|
||||
[MenuItem("BaseGames/Scene/Setup/Scaffold Persistent Scene")]
|
||||
public static void ScaffoldPersistentScene()
|
||||
{
|
||||
var report = new List<string>();
|
||||
@@ -235,7 +235,7 @@ namespace BaseGames.Editor
|
||||
/// [MainMenu] → [Canvas_MainMenu] → 主按钮组 / SaveSlotPanel / SettingsPanel / CreditsPanel
|
||||
/// 自动绑定所有已存在的相关事件频道 SO 资产。
|
||||
/// </summary>
|
||||
[MenuItem("BaseGames/Tools/Scaffold Main Menu Scene", priority = 202)]
|
||||
[MenuItem("BaseGames/Scene/Setup/Scaffold Main Menu Scene", priority = 202)]
|
||||
public static void ScaffoldMainMenuScene()
|
||||
{
|
||||
var report = new List<string>();
|
||||
@@ -305,7 +305,7 @@ namespace BaseGames.Editor
|
||||
/// [RoomRoot] → [Camera] / [SpawnPoints] / [Environment] / [Transitions]
|
||||
/// 可配合 SceneObjectPlacerTool 在层级内快速追加更多对象。
|
||||
/// </summary>
|
||||
[MenuItem("BaseGames/Tools/Scaffold Game Room", priority = 201)]
|
||||
[MenuItem("BaseGames/Scene/Setup/Scaffold Game Room", priority = 201)]
|
||||
public static void ScaffoldGameRoom()
|
||||
{
|
||||
var report = new List<string>();
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BaseGames.Editor
|
||||
// 场景
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
[MenuItem("BaseGames/Tools/Missing Scripts/Clear In Scene")]
|
||||
[MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Clear In Scene")]
|
||||
public static void ClearMissingScriptsInScene()
|
||||
{
|
||||
int totalRemoved = 0;
|
||||
@@ -39,7 +39,7 @@ namespace BaseGames.Editor
|
||||
Debug.Log($"[MissingScriptCleaner] 场景完成。共移除 {totalRemoved} 个丢失脚本,影响 {affected.Count} 个 GameObject。");
|
||||
}
|
||||
|
||||
[MenuItem("BaseGames/Tools/Missing Scripts/Find In Scene")]
|
||||
[MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Find In Scene")]
|
||||
public static void FindMissingScriptsInScene()
|
||||
{
|
||||
int totalFound = 0;
|
||||
@@ -67,7 +67,7 @@ namespace BaseGames.Editor
|
||||
// Prefab 资产
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
[MenuItem("BaseGames/Tools/Missing Scripts/Clear In All Prefabs")]
|
||||
[MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Clear In All Prefabs")]
|
||||
public static void ClearMissingScriptsInPrefabs()
|
||||
{
|
||||
int totalRemoved = 0;
|
||||
@@ -107,7 +107,7 @@ namespace BaseGames.Editor
|
||||
Debug.Log($"[MissingScriptCleaner] Prefab 完成。共移除 {totalRemoved} 个丢失脚本,影响 {affectedPrefabs} 个 Prefab。");
|
||||
}
|
||||
|
||||
[MenuItem("BaseGames/Tools/Missing Scripts/Find In All Prefabs")]
|
||||
[MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Find In All Prefabs")]
|
||||
public static void FindMissingScriptsInPrefabs()
|
||||
{
|
||||
int totalFound = 0;
|
||||
|
||||
@@ -54,14 +54,14 @@ namespace BaseGames.Editor
|
||||
};
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────
|
||||
[MenuItem("BaseGames/Tools/Physics2D Layer Matrix/Check", priority = 210)]
|
||||
[MenuItem("BaseGames/Tools/Maintenance/Physics2D Layer Matrix/Check", priority = 210)]
|
||||
public static void CheckAndPrintReport()
|
||||
{
|
||||
var results = Check();
|
||||
PrintToConsole(results);
|
||||
}
|
||||
|
||||
[MenuItem("BaseGames/Tools/Physics2D Layer Matrix/Auto Fix", priority = 211)]
|
||||
[MenuItem("BaseGames/Tools/Maintenance/Physics2D Layer Matrix/Auto Fix", priority = 211)]
|
||||
public static void FixAndReport()
|
||||
{
|
||||
var results = Check();
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace BaseGames.Editor
|
||||
+ string.Join("\n", errors));
|
||||
}
|
||||
|
||||
[MenuItem("BaseGames/Tools/Validate All ScriptableObjects")]
|
||||
[MenuItem("BaseGames/Tools/Validation/Validate All ScriptableObjects")]
|
||||
public static void ValidateMenu()
|
||||
{
|
||||
var (errors, warnings) = RunAll();
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace BaseGames.Editor
|
||||
new OrderRule("PlayerController", -100),
|
||||
};
|
||||
|
||||
[MenuItem("BaseGames/Tools/Apply Script Execution Order Preset")]
|
||||
[MenuItem("BaseGames/Tools/Validation/Apply Script Execution Order Preset")]
|
||||
public static void ApplyPreset()
|
||||
{
|
||||
int updated = 0;
|
||||
@@ -69,7 +69,7 @@ namespace BaseGames.Editor
|
||||
Debug.Log($"[ScriptExecutionOrderTools] 执行顺序预设应用完成。更新数量: {updated}。");
|
||||
}
|
||||
|
||||
[MenuItem("BaseGames/Tools/Validate Script Execution Order Preset")]
|
||||
[MenuItem("BaseGames/Tools/Validation/Validate Script Execution Order Preset")]
|
||||
public static void ValidatePreset()
|
||||
{
|
||||
var mismatches = new List<string>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08a52815a08c8c3428ccb6a530171ddd
|
||||
guid: a1f0dd89654be0841be1adfcea426a67
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,9 +1,9 @@
|
||||
# Addressables Label(标签)命名与使用规范
|
||||
|
||||
> **版本**:1.0
|
||||
> **版本**:1.1
|
||||
> **创建日期**:2026-05
|
||||
> **适用范围**:`Assets/_Game/` 目录下所有注册到 Addressables 的资产
|
||||
> **关联文档**:`Standards/AssetFolderSpec.md §8`、`Scripts/Core/Assets/AddressKeys.cs`
|
||||
> **关联文档**:`Standards/AssetFolderSpec.md §8`、`Scripts/Core/Assets/AddressKeys.cs`、`Scripts/Editor/Addressables/AddressableRules.cs`
|
||||
|
||||
---
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
4. [AddressKeys.cs 常量对照](#4-addresskeyscs-常量对照)
|
||||
5. [使用规范与禁止行为](#5-使用规范与禁止行为)
|
||||
6. [新增 Label 决策流程](#6-新增-label-决策流程)
|
||||
7. [工具链与自动化](#7-工具链与自动化)
|
||||
|
||||
---
|
||||
|
||||
@@ -255,8 +256,62 @@ await Addressables.DownloadDependenciesAsync("Preload", false);
|
||||
│
|
||||
新增 Label 的执行步骤:
|
||||
1. 在 AddressKeys.Labels 类中添加 public const string {Name} = "{Name}";
|
||||
2. 在 Addressables Groups 窗口 → Label 列表中创建同名标签
|
||||
3. 在本文档 §2 Label 清单中追加说明行
|
||||
4. 在本文档 §3 对应资产类型的表格中标注
|
||||
5. 运行 AddressKeyValidator 验证无遗漏
|
||||
2. 在 AddressableRules.cs 的 PrefixLabelMap / ExactLabelMap 中添加对应映射规则
|
||||
3. 在 Addressables Groups 窗口 → Label 列表中创建同名标签
|
||||
4. 在本文档 §2 Label 清单中追加说明行
|
||||
5. 在本文档 §3 对应资产类型的表格中标注
|
||||
6. 运行 Rule Sync(菜单 BaseGames → Addressables → Rule Sync)Scan 验证无遗漏
|
||||
7. 运行 AddressKeyValidator(菜单 BaseGames → Verification → Validate Address Keys)确认
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 工具链与自动化
|
||||
|
||||
### 7.1 规则权威来源
|
||||
|
||||
所有分组与标签的映射规则**集中定义**于:
|
||||
|
||||
```
|
||||
Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs
|
||||
```
|
||||
|
||||
- `PrefixGroupMap` — 地址前缀 → Group 名称
|
||||
- `PrefixLabelMap` — 地址前缀 → Label 列表(更具体的前缀排在前面)
|
||||
- `ExactLabelMap` — 精确地址 → Label 列表(覆盖前缀规则的特殊情况)
|
||||
|
||||
**修改规则时只改 `AddressableRules.cs` 一处**,两个工具(`AddressableBatchTool` 和 `AddressableRuleSyncWindow`)均从此处读取,保证一致性。
|
||||
|
||||
### 7.2 日常标签维护工作流
|
||||
|
||||
```
|
||||
新建/更新资产后:
|
||||
1. 打开 Rule Sync 窗口(菜单 BaseGames → Addressables → Rule Sync)
|
||||
2. 点击 [Scan All] — 扫描所有 Addressable 条目与期望规则的差异
|
||||
3. 查看报告:
|
||||
- Group Mismatch — 资产在错误的分组
|
||||
- Label Missing — 缺少应有标签
|
||||
- Label Extra — 存在不应有的标签
|
||||
4. 点击 [Fix All] 或逐条点击 [Fix] 自动修复
|
||||
5. 可选:点击 [Export CSV] 导出差异报告存档
|
||||
6. 运行 Validate Address Keys 做最终验证
|
||||
```
|
||||
|
||||
### 7.3 批量注册工作流(新增大量资产)
|
||||
|
||||
```
|
||||
1. 将资产按命名前缀放置到正确目录(见 AssetFolderSpec.md §2–§4)
|
||||
2. 打开 Addressable Batch Tool(菜单 BaseGames → Tools → Addressable Batch Tool)
|
||||
3. 切换到 "② 文件夹批量" 标签,选择目标文件夹,点击 [Register Folder]
|
||||
4. 切换到 "① 同步 AddressKeys" 标签,点击 [Scan],为新注册的资产补充 AddressKeys.cs 常量
|
||||
5. 返回 Rule Sync 窗口执行 Scan → Fix All 统一校正 Group / Label
|
||||
6. 运行 Validate Address Keys 验证
|
||||
```
|
||||
|
||||
### 7.4 工具一览
|
||||
|
||||
| 工具 | 菜单路径 | 核心功能 |
|
||||
|------|---------|---------|
|
||||
| **Rule Sync** | `BaseGames → Addressables → Rule Sync` | 扫描 + 修复分组/标签不合规条目;导出 CSV |
|
||||
| **Addressable Batch Tool** | `BaseGames → Tools → Addressable Batch Tool` | 三标签:AddressKeys 同步 / 文件夹批量注册 / Selection 注册 |
|
||||
| **Validate Address Keys** | `BaseGames → Verification → Validate Address Keys` | 验证 AddressKeys.cs 所有常量均已在 Addressables 注册,构建前自动触发 |
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
10. [Import Settings 规范](#9-import-settings-规范)
|
||||
11. [资源新增工作流](#10-资源新增工作流)
|
||||
12. [禁止行为清单](#11-禁止行为清单)
|
||||
13. [编辑器工具参考](#12-编辑器工具参考)
|
||||
|
||||
---
|
||||
|
||||
@@ -642,6 +643,8 @@ var (prefab, _) = await AssetLoader.LoadAsync<GameObject>(AddressKeys.PrefabPlay
|
||||
|
||||
### 10.1 新增敌人
|
||||
|
||||
> **推荐工具**:`BaseGames → Data → Enemy Data Manager`(`EnemyDataWindow`)——在左栏点击 [New] 可自动创建 `ENM_*_Stats.asset`,在右栏 Loot Tab 配置掉落表。
|
||||
|
||||
```
|
||||
1. _Game/Art/Characters/Enemies/ 下创建 {EnemyID}/ 目录,内含 Sprites/ Animations/ Materials/ Atlases/
|
||||
2. 导入 Sprite Sheet 到 Sprites/,配置 Import Settings(PPU=32, Filter=Point, Multiple)
|
||||
@@ -649,25 +652,88 @@ var (prefab, _) = await AssetLoader.LoadAsync<GameObject>(AddressKeys.PrefabPlay
|
||||
4. 在 Animations/ 下创建动画片段(.anim)和 Animator Controller
|
||||
5. 在 Materials/ 下创建材质(引用 _Game/Shaders/ 中的角色 Shader,关联主纹理和 Emission 贴图)
|
||||
6. 在 Atlases/ 下创建 Atlas_Enemy_{ID}.spriteatlas,包含该敌人所有 Sprite
|
||||
7. 在 _Game/Data/Enemies/{EnemyID}/ 下创建 ENM_*_Stats.asset 等 SO
|
||||
7. 在 Enemy Data Manager(菜单 BaseGames/Data/Enemy Data Manager)创建 ENM_{ID}_Stats.asset
|
||||
8. 在 _Game/Prefabs/Enemies/{EnemyID}/ 下创建 ENM_{Name}.prefab
|
||||
9. 在 AddressKeys.cs 中添加 PrefabEnemy{Name} 常量
|
||||
10. 使用 AddressableBatchTool 注册到 Enemies_{Region} 组,添加 Enemy 标签
|
||||
11. 运行 AddressKeyValidator 验证
|
||||
10. 使用 Rule Sync(菜单 BaseGames/Addressables/Rule Sync)Scan → Fix All,自动分组并打 Enemy 标签
|
||||
11. 运行 AddressKeyValidator(菜单 BaseGames/Addressables/Validate Address Keys)验证
|
||||
```
|
||||
|
||||
### 10.2 新增 VFX
|
||||
### 10.2 新增武器(Weapon)
|
||||
|
||||
> **推荐工具**:`BaseGames → Data → Weapon Editor`(`WeaponEditorWindow`)创建 `WPN_*_Data.asset`;`BaseGames → Create → Weapon HitBox Prefab`(`WeaponHitBoxWizard`)创建 4 方向 HitBox Prefab。
|
||||
|
||||
```
|
||||
1. 在 _Game/Art/Characters/Player/{FormID}/Sprites/ 下放置武器帧动画 Sprite Sheet,配置 Import Settings
|
||||
2. 在 Weapon Editor(菜单 BaseGames/Data/Weapon Editor)左栏 [New] 创建 WPN_{Name}_Data.asset
|
||||
- 路径:_Game/Data/Combat/Weapons/WPN_{Name}_Data.asset
|
||||
- 命名:WPN_{Name}(示例:WPN_SkyBlade、WPN_EarthClaw)
|
||||
3. 使用 Weapon HitBox Wizard(菜单 BaseGames/Create/Weapon HitBox Prefab)生成
|
||||
_Game/Prefabs/Weapons/WPN_{Name}_HitBox.prefab(自动创建 4 方向 Ground/Up/Down/Air)
|
||||
4. 在 _Game/Prefabs/Player/ 下创建或更新武器顶级 Prefab WPN_{Name}.prefab
|
||||
5. 在 AddressKeys.cs 中添加 PrefabWeapon{Name} 常量
|
||||
6. 使用 Rule Sync 自动分组(Player 组)并打 Weapon + Preload 标签
|
||||
7. 运行 AddressKeyValidator 验证
|
||||
```
|
||||
|
||||
### 10.3 新增技能(Skill)
|
||||
|
||||
> **推荐工具**:`BaseGames → Data → Skill Editor`(`SkillEditorWindow`)创建 `SKL_*_Data.asset`;`BaseGames → Create → Skill HitBox Prefab`(`SkillHitBoxWizard`)创建多段 HitBox Prefab。
|
||||
|
||||
```
|
||||
1. 在 _Game/Art/Characters/Player/{FormID}/Animations/ 下创建技能动画片段(.anim)
|
||||
2. 在 Skill Editor(菜单 BaseGames/Data/Skill Editor)左栏 [New] 创建 SKL_{SkillID}_Data.asset
|
||||
- 路径:_Game/Data/Player/Skills/SKL_{SkillID}_Data.asset
|
||||
- 命名:SKL_{SkillID}(示例:SKL_DashSlash、SKL_SpiritWave)
|
||||
3. 使用 Skill HitBox Wizard(菜单 BaseGames/Create/Skill HitBox Prefab)生成
|
||||
_Game/Prefabs/Skills/SKL_{SkillID}_HitBox.prefab(支持多段伤害配置)
|
||||
4. 在 AddressKeys.cs 中添加对应常量(如需独立 Addressable 加载)
|
||||
5. 运行 AddressKeyValidator 验证(如已注册 Addressable)
|
||||
```
|
||||
|
||||
### 10.4 新增护身符(Charm)
|
||||
|
||||
> **推荐工具**:直接在 Project 窗口 Create → 对应 CharmSO,然后通过 CharmSOEditor(Custom Inspector)配置效果类型与参数。
|
||||
|
||||
```
|
||||
1. 在 _Game/Data/Progression/Charms/ 下创建 CHM_{Name}.asset(CharmSO)
|
||||
- 命名:CHM_{Name}(示例:CHM_SoulReaper、CHM_IronSkin)
|
||||
2. 在 Inspector 中通过 CharmSOEditor 下拉选择效果类型并配置参数
|
||||
3. 在 AddressKeys.cs 中添加 DataCharm{Name} 常量
|
||||
4. 使用 Rule Sync 自动分组(Config 组)并打 Charms 标签
|
||||
5. 运行 AddressKeyValidator 验证
|
||||
```
|
||||
|
||||
### 10.5 新增玩家形态(Player Form)
|
||||
|
||||
> **推荐工具**:`BaseGames → Tools → Character Wizard`(`CharacterWizardWindow`)统一入口——创建 FormSO、绑定武器引用、跳转到 Form Editor;`BaseGames → Data → Form Editor`(`FormEditorWindow`)进行三魂列阵可视化编辑。
|
||||
|
||||
```
|
||||
1. 在 Character Wizard(菜单 BaseGames/Data/Character Wizard)切换到 Player 标签
|
||||
- 填写 FormID,点击 [Create Form Assets],自动在正确路径创建 FormSO 和相关 SO
|
||||
2. 在 _Game/Art/Characters/Player/{FormID}/ 下创建 Sprites/ Animations/ Materials/ Atlases/ 目录
|
||||
3. 导入 Sprite Sheet,配置 Import Settings(PPU=32, Filter=Point, Multiple)
|
||||
4. 在 Form Editor(菜单 BaseGames/Data/Form Editor)三栏网格中选择形态格位,绑定武器和技能列表
|
||||
5. 在 _Game/Prefabs/Player/ 下创建 PLY_{FormID}.prefab
|
||||
6. 在 AddressKeys.cs 中添加 PrefabPlayer{FormID} 常量(如为独立 Addressable)
|
||||
7. 使用 Rule Sync 自动分组(Player 组)并打 Preload 标签
|
||||
8. 运行 AddressKeyValidator 验证
|
||||
```
|
||||
|
||||
### 10.6 新增 VFX
|
||||
|
||||
> **提示**:VFX Prefab 必须纳入 `GlobalObjectPool`,在 Pool 配置中指定初始预热数量。
|
||||
|
||||
```
|
||||
1. 在 _Game/Art/Effects/Sprites/ 下导入特效 Sprite Sheet,配置 Import Settings(PPU=32, Filter=Point)
|
||||
2. 在 _Game/Art/Effects/Materials/ 下创建特效材质
|
||||
3. 在 _Game/Prefabs/Effects/ 下创建 VFX_{Name}.prefab
|
||||
4. 在 AddressKeys.cs 中添加 PrefabVFX{Name} 常量
|
||||
5. 使用 AddressableBatchTool 注册到 VFX_Common 组,添加 Poolable 标签
|
||||
6. 在 AssetReleaseTracker 配套的 Pool 中注册(纳入对象池)
|
||||
5. 使用 Rule Sync 自动分组(VFX_Common 组)并打 Poolable + Preload 标签
|
||||
6. 在 GlobalObjectPool._warmupConfigs 中添加初始池数量配置
|
||||
```
|
||||
|
||||
### 10.3 新增 UI 界面
|
||||
### 10.7 新增 UI 界面
|
||||
|
||||
```
|
||||
1. 在 _Game/UI Toolkit/Layouts/ 下创建 {PanelName}.uxml
|
||||
@@ -675,15 +741,15 @@ var (prefab, _) = await AssetLoader.LoadAsync<GameObject>(AddressKeys.PrefabPlay
|
||||
3. 在 _Game/Prefabs/UI/ 下创建 UI_{PanelName}.prefab
|
||||
4. 在 _Game/Data/UI/Panels/ 下创建 UI_PanelConfig_{PanelName}.asset(如需配置 SO)
|
||||
5. 在 AddressKeys.cs 中添加 PrefabUI{PanelName} 常量
|
||||
6. 使用 AddressableBatchTool 注册到 UI 组
|
||||
6. 使用 Rule Sync 自动分组(UI 组);常驻全局面板额外打 Preload 标签
|
||||
```
|
||||
|
||||
### 10.4 新增关卡场景
|
||||
### 10.8 新增关卡场景
|
||||
|
||||
```
|
||||
1. 在 _Game/Scenes/ 下创建 Room_{Region}_{Index:D2}.unity
|
||||
2. 在 AddressKeys.cs 中添加地址常量(复用 SceneRoomPrefix + 动态拼接或新增独立常量)
|
||||
3. 将场景注册到 Room_{Region} 组
|
||||
3. 将场景注册到 Room_{Region} 组(Rule Sync 可自动识别 Room_ 前缀并动态计算组名)
|
||||
4. 在 _Game/Data/World/Map/ 下创建 MAP_RoomData_{Region}_{Index:D2}.asset
|
||||
```
|
||||
|
||||
@@ -705,3 +771,68 @@ var (prefab, _) = await AssetLoader.LoadAsync<GameObject>(AddressKeys.PrefabPlay
|
||||
| 第三方插件目录内创建自定义资产 | 插件升级时被覆盖 | 自定义内容放在 `_Game/` 下对应模块目录 |
|
||||
| 将 `_Game/` 内的资产移到 `Assets/` 根目录 | 破坏第一方/第三方隔离原则 | 所有自有资产必须在 `_Game/` 内 |
|
||||
| 将 `AddressableAssetsData/` 移入 `_Game/` | Unity 硬编码此路径,移动后 Addressables 完全失效 | 永远保留在 `Assets/` 根目录 |
|
||||
| 绕过编辑器工具手动创建 SO / Prefab | 路径或命名不符合规范,导致 Addressables 工具误报 | 使用 §12 中的对应编辑器窗口创建 |
|
||||
|
||||
---
|
||||
|
||||
## 12. 编辑器工具参考
|
||||
|
||||
所有**资产创建**均应通过以下编辑器工具进行,以保证路径、命名、Addressables 注册完全符合本规范。
|
||||
|
||||
### 12.1 资产创建工具
|
||||
|
||||
| 工具名称 | 菜单路径 | 负责资产类型 | 说明 |
|
||||
|---------|---------|------------|------|
|
||||
| **Character Wizard** | `BaseGames/Data/Character Wizard` | 角色 SO(玩家形态 / Minion / Boss 通用入口) | 统一入口,自动在正确路径创建所有配套 SO,内含快捷跳转按钮 |
|
||||
| **Form Editor** | `BaseGames/Data/Form Editor` | 玩家三魂形态(FormSO) | 三栏可视化网格,自动绑定武器/技能引用,支持 TianHun / DiHun / MingHun |
|
||||
| **Enemy Data Manager** | `BaseGames/Data/Enemy Data Manager` | 敌人配置 SO(`ENM_*_Stats.asset`)+ 掉落表 | 双面板列表编辑,左栏搜索 + [New],右栏 Stats/Loot 标签 |
|
||||
| **Boss Skill Sequence** | `BaseGames/Data/Boss Skill Sequence` | Boss 技能阶段(BossSkillSO / SkillSequenceSO) | Gantt 时间轴可视化,Windup / Active / Recovery 三段颜色标记 |
|
||||
| **Skill Editor** | `BaseGames/Data/Skill Editor` | 技能配置 SO(`SKL_*_Data.asset`) | 按 SkillEffectType 分组筛选,右栏含 HitBox 验证 + 资源费预览 |
|
||||
| **Weapon Editor** | `BaseGames/Data/Weapon Editor` | 武器配置 SO(`WPN_*_Data.asset`) | 双面板列表,右栏全属性 + HitBox Prefab 验证 + 快捷操作 |
|
||||
| **Weapon HitBox Wizard** | `BaseGames/Create/Weapon HitBox Prefab` | 武器 HitBox Prefab(4 方向 Ground/Up/Down/Air) | 自动生成 `WPN_{ID}_HitBox.prefab`,支持各方向碰撞体形状配置 |
|
||||
| **Skill HitBox Wizard** | `BaseGames/Create/Skill HitBox Prefab` | 技能 HitBox Prefab(多段伤害支持) | 自动生成 `SKL_{ID}_HitBox.prefab`,可配置 1–4 段 hitBoxCount |
|
||||
|
||||
### 12.2 场景搭建工具
|
||||
|
||||
| 工具名称 | 菜单路径 | 说明 |
|
||||
|---------|---------|------|
|
||||
| **Boot Flow Wizard** | `BaseGames/Scene/Setup/Boot Flow Wizard` | 4 步启动流程一键配置(事件频道 → Persistent 场景 → MainMenu → 验证) |
|
||||
| **Scaffold Persistent Scene** | `BaseGames/Scene/Setup/Scaffold Persistent Scene` | 一键创建 Persistent 场景的 Services/Input/Camera/UI 层次结构 |
|
||||
| **Scaffold Main Menu Scene** | `BaseGames/Scene/Setup/Scaffold Main Menu Scene` | 一键创建 MainMenu 场景基础层次结构 |
|
||||
| **Scaffold Game Room** | `BaseGames/Scene/Setup/Scaffold Game Room` | 一键创建关卡房间场景基础层次结构 |
|
||||
| **Persistent Auto-Loader** | `BaseGames/Scene/Setup/Auto-Open Persistent Scene` | 编辑模式下打开任意场景时自动附加 Persistent(Toggle,仅编辑模式) |
|
||||
| **Scene Object Placer** | `BaseGames/Scene/Place/{类型}` | 场景中快速放置角色/陷阱/检查点/摄像机等,自动绑定组件和事件频道 |
|
||||
| **Camera Area Setup** | `BaseGames/Scene/Camera Area Setup` | 在当前场景中快速创建并配置摄像机区域 |
|
||||
| **Bake All NavSurfaces** | `BaseGames/Scene/Bake All NavSurfaces` (Ctrl+Shift+B) | 一键烘焙场景中所有 NavSurface,仅编辑模式可用 |
|
||||
|
||||
### 12.3 Addressables 管理工具
|
||||
|
||||
| 工具名称 | 菜单路径 | 说明 |
|
||||
|---------|---------|------|
|
||||
| **Rule Sync** | `BaseGames/Addressables/Rule Sync` | 批量扫描/修复分组和标签(基于 `AddressableRules.cs` 规则,支持导出 CSV) |
|
||||
| **Addressable Batch Tool** | `BaseGames/Addressables/Addressable Batch Tool` (Alt+Shift+A) | 三标签操作:① 同步 AddressKeys → ② 文件夹批量注册 → ③ Selection 注册 |
|
||||
| **Asset Reference Graph** | `BaseGames/Addressables/Asset Reference Graph` | 可视化 Addressable 地址间的引用依赖关系 |
|
||||
| **Validate Address Keys** | `BaseGames/Addressables/Validate Address Keys` | 验证 `AddressKeys.cs` 所有常量在 Addressables 中均已注册,构建前自动触发 |
|
||||
|
||||
### 12.4 事件系统工具
|
||||
|
||||
| 工具名称 | 菜单路径 | 说明 |
|
||||
|---------|---------|------|
|
||||
| **Event Bus Monitor** | `BaseGames/Events/Event Bus Monitor` (Ctrl+Shift+E) | 运行时事件派发监控(类型/侦听器数/触发次数实时显示) |
|
||||
| **Event Chain Viewer** | `BaseGames/Events/Event Chain Viewer` | 叙事事件链可视化,运行时显示完成/满足/等待状态 |
|
||||
| **Create Event Channels** | `BaseGames/Events/Create Event Channels` | 一键生成全局事件频道 SO(幂等,跳过已存在资产) |
|
||||
| **Reimport Event Channels** | `BaseGames/Events/Reimport Event Channels` | 重新导入/刷新全局事件频道 SO |
|
||||
|
||||
### 12.5 工具与维护
|
||||
|
||||
| 工具名称 | 菜单路径 | 说明 |
|
||||
|---------|---------|------|
|
||||
| **SO Manager** | `BaseGames/Tools/SO Manager` | 全项目 ScriptableObject 浏览器,支持类型/路径搜索 + Ping |
|
||||
| **GM Debug Tool** | `BaseGames/Tools/GM Debug Tool` | 运行时快速注入资源/切换形态/解锁技能(仅 PlayMode) |
|
||||
| **Validate All SOs** | `BaseGames/Tools/Validation/Validate All ScriptableObjects` | 扫描所有 `IValidatable` SO 并报告错误(构建前自动触发) |
|
||||
| **Apply Script Order** | `BaseGames/Tools/Validation/Apply Script Execution Order Preset` | 将脚本执行顺序预设应用到项目 |
|
||||
| **Validate Script Order** | `BaseGames/Tools/Validation/Validate Script Execution Order Preset` | 验证当前脚本执行顺序是否符合预设 |
|
||||
| **Missing Scripts (Scene)** | `BaseGames/Tools/Maintenance/Missing Scripts/...` | 在场景/Prefab 中查找或清除 Missing Script 引用 |
|
||||
| **Physics2D Layer Matrix** | `BaseGames/Tools/Maintenance/Physics2D Layer Matrix/...` | 检查或自动修复 Physics2D 层碰撞矩阵配置 |
|
||||
|
||||
> **原则**:新增资产类型时,必须同步在对应编辑器工具中增加创建入口;严禁绕过工具手动在 Project 窗口 "Create" 并手动填写路径/命名,否则将导致 Addressables Rule Sync 工具误报分组或标签不一致。
|
||||
Reference in New Issue
Block a user