# 程序集三层拆分方案 最后更新:2026-04-30 ## 1. 设计目标 将项目拆分为三层,逐步解耦 Unity 依赖,实现核心业务逻辑的可测试性和可移植性: - **L0(Domain)**:纯 C# 业务层,引用 GameFramework.dll 作为基础设施,可在独立解决方案中构建 - **L1(Infrastructure)**:胶水层,连接 L0 与 Unity Runtime 类型 - **L2(Presentation)**:表现层,Unity MonoBehaviour、UGuiForm、Entity 实现 --- ## 2. GameFramework.dll 复用 项目自带的 `Assets/GameFramework/Libraries/GameFramework.dll` 是 **纯 C# 实现**的 GameFramework 核心库,包含 19 个模块。L0 直接引用此 DLL,无需重新实现。 ### 2.1 可直接使用的模块 | 模块 | 提供内容 | L0 使用方式 | |------|---------|-----------| | **Event** | `EventManager`, `GameEventArgs` | `GameEntry.Event` 替换为 `EventManager` | | **ObjectPool** | `ObjectPoolManager`, `ObjectBase` | 继承 `ObjectBase`,无需自己实现池 | | **Fsm** | `FsmManager`, `FsmState`, `FsmState` | 继承 `FsmState` 构建状态机 | | **ReferencePool** | `ReferencePool` | `ReferencePool.Acquire()` / `Release()` | | **DataNode** | 树状数据结构 | 直接使用 | | **Utility** | 通用工具类 | 直接使用 | | **Config** | 配置管理 | 直接使用 | | **DataTable** | 表格加载解析 | 数据行类依赖 GameFramework | ### 2.2 需要 Unity 适配的模块 以下模块需要 L1 提供 Unity 特定实现: | 模块 | 原因 | L1 适配职责 | |------|------|------------| | **Resource** | 依赖 Unity Resources/AssetDatabase | 实现 `IResourceManager` | | **Scene** | 依赖 Unity SceneManager | 实现 `ISceneManager` | | **Entity** | 依赖 Unity GameObject | 实现 `IEntityManager` | | **UI** | 依赖 Unity UGUI | 实现 `IUIFormManager` | | **Sound** | 依赖 Unity Audio | 实现 `ISoundManager` | ### 2.3 复用带来的简化 ``` 传统方案(自研基础设施) ├── 需要自己实现事件系统 ├── 需要自己实现对象池基类 ├── 需要自己实现状态机框架 └── 大量基础设施代码 GameFramework.dll 方案 ├── 事件 → GameFramework.Event.EventManager ├── 对象池 → GameFramework.ObjectPool ├── 状态机 → GameFramework.Fsm └── 专注业务逻辑实现 ``` --- ## 3. 三层职责定义 ### L0 - Domain(纯 C# 业务层) - 引用 `GameFramework.dll`,使用其提供的 Event/ObjectPool/Fsm 等基础设施 - 包含所有业务规则、状态机、领域逻辑 - 无 `using UnityEngine`、`using UnityGameFramework.Runtime` - 通过接口与 L1 通信 - 在独立 .sln 中构建,输出 DLL 导入 Unity ### L1 - Infrastructure(胶水层) - 实现 GameFramework 的 Unity 特定接口(Resource/Scene/Entity/UI/Sound) - 实现 L0 定义的扩展接口(如 `ICombatEventHandler`) - 持有 L0 服务实例,管理 Unity 生命周期 - 直接依赖 UnityEngine 和 GameFramework.Runtime ### L2 - Presentation(表现层) - 所有 `MonoBehaviour` 类 - View 层(UGuiForm 具体实现) - Entity Logic(Player、Enemy、Tower 具体实体) - ECS 组件(MovementComponent、ShooterBullet 等) --- ## 4. 程序集映射 ### 4.1 L0 程序集 ``` GeometryTD.Domain/ ← 引用 GameFramework.dll ├── Definition/ │ ├── Enum/ # 所有枚举类型 │ ├── Constant/ # 常量定义 │ ├── DataStruct/ # 纯数据结构(AttackPayload, TowerStatsData 等) │ └── Tag/ │ ├── Aggregation/ # Tag 汇总服务 │ ├── Generation/ # Tag 生成规则 │ ├── Metadata/ # Tag 定义元数据 │ └── Combat/ # Tag 效果解析 │ ├── GameFramework/ # GameFramework.dll 直接使用 │ └── Event/ # 自定义事件 args,继承 GameEventArgs │ ├── CustomComponent/ │ ├── CombatNode/ # 战斗域 │ │ ├── CombatScheduler # 基于 GameFramework.Fsm │ │ ├── EnemyManager # 敌人生成、追踪 │ │ ├── CombatRunResourceStore # 战斗资源存储 │ │ └── CombatSettlementCalculator │ ├── PlayerInventory/ # 背包、交易、组装服务 │ └── InventoryGeneration/ # 掉落、商店、奖励生成 │ ├── UI/ │ ├── Base/ │ │ ├── IUIUseCase.cs │ │ └── UIContext.cs │ ├── Combat/ │ │ ├── UseCase/ # CombatSelectFormUseCase, CombatInfoFormUseCase │ │ ├── RawData/ │ │ └── Context/ │ ├── Game/ │ │ ├── UseCase/ # EventFormUseCase, NodeMapFormUseCase, RepoFormUseCase │ │ ├── RawData/ │ │ └── Context/ │ └── General/ │ ├── UseCase/ │ ├── RawData/ │ └── Context/ │ └── Utility/ ├── InventoryCloneUtility.cs ├── EnumUtility.cs └── InventoryRarityRuleService.cs ``` ### 4.2 L1 程序集 ``` GeometryTD.Infrastructure/ ├── GameFramework/ # GameFramework Unity 适配 │ ├── Resource/ # 实现 IResourceManager │ ├── Scene/ # 实现 ISceneManager │ ├── Entity/ # 实现 IEntityManager │ ├── UI/ # 实现 IUIFormManager │ └── Sound/ # 实现 ISoundManager │ ├── CustomComponent/ │ ├── CombatNode/ │ │ └── CombatNodeComponent.cs # Unity Component │ ├── PlayerInventory/ │ │ └── PlayerInventoryComponent.cs │ ├── InventoryGeneration/ │ │ └── InventoryGenerationComponent.cs │ ├── EventNodeComponent.cs │ ├── ShopNodeComponent.cs │ ├── TagRegistry/ │ │ └── TagRegistryComponent.cs │ └── BuiltinDataComponent.cs │ ├── Scene/ │ └── Map/ │ ├── MapTopologyService.cs # Tilemap 扫描 │ ├── TowerPlacementService.cs # 依赖 GameEntry.Entity │ ├── TowerSelectionPresenter.cs │ └── MapCombatRuntimeBridge.cs │ ├── Entity/ │ ├── EntityLogic/ │ │ ├── EntityBase.cs │ │ ├── CombatSelectInputService.cs │ │ ├── CombatSelectUseCaseConfigurator.cs │ │ └── MapEntity.cs │ ├── EntityData/ # Unity 可序列化 │ │ ├── MapData.cs │ │ ├── TowerData.cs │ │ ├── EnemyData.cs │ │ └── BulletData.cs │ └── EntityExtension.cs │ ├── UI/ │ ├── Base/ # Unity 相关基类 │ │ ├── UGuiForm.cs │ │ ├── UGuiGroupHelper.cs │ │ ├── UIFormControllerCommonBase.cs │ │ ├── UIExtension.cs │ │ └── UIFormControllerBase.cs │ └── Combat/ │ └── Controller/ │ ├── DataTable/ # GameFramework.DataTable 依赖 │ └── DR*.cs │ └── Procedure/ # GameFramework.Procedure └── ProcedureMain/ ``` ### 4.3 L2 程序集 ``` GeometryTD.Presentation/ ├── UI/ │ ├── Combat/ │ │ └── View/ │ ├── Game/ │ │ └── View/ │ ├── General/ │ │ └── View/ │ ├── Templates/ │ └── Common/ │ ├── Entity/ │ └── EntityLogic/ │ ├── Player.cs │ ├── Enemy.cs │ ├── TowerEntity.cs │ ├── BulletEntity.cs │ └── EnemyTagStatusRuntime.cs │ └── Components/ ├── MovementComponent.cs ├── ShooterBullet.cs ├── ShooterMuzzleComp.cs ├── TowerController.cs ├── InputComponent.cs ├── BasicBaseComp.cs └── BasicBearingComp.cs ``` --- ## 5. GameFramework 集成方式 ### 5.1 事件系统 L0 使用 GameFramework 内置的 `EventManager`,无需自己实现事件系统: ```csharp // L0: 定义游戏事件,继承 GameFramework.Event.GameEventArgs public class CombatCoinChangedEventArgs : GameEventArgs { public const int EventId = typeof(CombatCoinChangedEventArgs).GetHashCode(); public int CurrentCoin { get; private set; } public int Delta { get; private set; } public CombatCoinChangedEventArgs() { } public CombatCoinChangedEventArgs(int currentCoin, int delta) { CurrentCoin = currentCoin; Delta = delta; } } // L0: 服务中使用 public class CombatRunResourceStore { private IEventManager _event; public CombatRunResourceStore(IEventManager eventManager) { _event = eventManager; } public void AddCoin(int amount) { CurrentCoin += amount; _event.Fire(this, CombatCoinChangedEventArgs.Create(CurrentCoin, amount)); } } ``` ### 5.2 状态机 L0 使用 GameFramework 的 Fsm 模块: ```csharp // L0: 战斗状态机基于 GameFramework.Fsm public interface ICombatFsm { } // 空接口,用于泛型约束 public class CombatScheduler { private IFsmManager _fsmManager; private CombatSchedulerRuntime _runtime; public CombatScheduler(IFsmManager fsmManager) { _fsmManager = fsmManager; _runtime = new CombatSchedulerRuntime(); } public void Start() { _fsmManager.CreateFsm(this, new CombatLoadingState(), new CombatRunningPhaseState(), new CombatWaitingForPhaseEndState(), new CombatSettlementState()); } } // L0: 具体状态继承 FsmState public class CombatRunningPhaseState : FsmState { protected internal override void OnEnter(ICombatFsm fsmOwner) { // 初始化 } protected internal override void OnUpdate(ICombatFsm fsmOwner, float elapseSeconds) { // 每帧更新 } protected internal override void OnLeave(ICombatFsm fsmOwner, bool isShutdown) { // 清理 } } ``` ### 5.3 对象池 L0 使用 GameFramework 的 ObjectPool: ```csharp // L0: 敌人继承 ObjectBase public class EnemyObject : ObjectBase { public int EnemyId { get; private set; } public int Health { get; private set; } protected internal override void OnSpawn(bool isRecycle) { // 激活时调用 } protected internal override void OnDespawn(bool isRecycle) { // 回收时调用 } public void Initialize(int enemyId, int health) { EnemyId = enemyId; Health = health; } } // L0: 使用对象池 public class EnemyManager { private IObjectPoolManager _poolManager; public EnemyManager(IObjectPoolManager poolManager) { _poolManager = poolManager; } public void SpawnEnemy(int enemyId, int health) { var pool = _poolManager.GetOrCreateObjectPool("EnemyPool"); var enemy = EnemyObject.Create(enemyId, health); pool.Register(enemy, true); } } ``` --- ## 6. L1 桥接设计 ### 6.1 GameFramework Unity 适配接口 GameFramework.dll 定义了以下接口,L1 需要提供 Unity 实现: ```csharp // GameFramework 定义的接口(L0 引用) namespace GameFramework.Resource { public interface IResourceManager { void LoadAsset(string assetName, LoadAssetCallbacks callbacks, object userData); void UnloadAsset(string assetName); // ... } } // L1: Unity 实现 public class UnityResourceManager : IResourceManager { public void LoadAsset(string assetName, LoadAssetCallbacks callbacks, object userData) { // 使用 Unity Resources.Load 或 Addressables } } ``` ### 6.2 L0 服务生命周期管理 ```csharp // L1: Unity Component 持有 L0 服务实例 public class CombatNodeComponent : GameFrameworkComponent { private IEventManager _eventManager; private IObjectPoolManager _poolManager; private IFsmManager _fsmManager; // L0 服务 private CombatScheduler _scheduler; private EnemyManager _enemyManager; private void Awake() { // 初始化 GameFramework Unity 适配器 _eventManager = GameEntry.GetComponent(); _poolManager = GameEntry.GetComponent(); _fsmManager = GameEntry.GetComponent(); // 初始化 L0 服务(注入依赖) _enemyManager = new EnemyManager(_poolManager); _scheduler = new CombatScheduler(_fsmManager, _enemyManager); } } ``` --- ## 7. Unity 类型处理策略 ### 7.1 Vector3 / Quaternion / Color | 类型 | 方案 | |------|------| | `Vector3` | 使用 `System.Numerics.Vector3`,GameFramework 内部已使用 | | `Quaternion` | 使用 `System.Numerics.Quaternion` | | `Color` | 定义纯 C# Color 结构 `{ float r, g, b, a; }` | ### 7.2 [Serializable] ```csharp // L0: POCO 数据结构 public class TowerStatsData { public int[] AttackDamage { get; set; } public float[] AttackSpeed { get; set; } } // L1: Unity 可序列化 DTO [Serializable] public class TowerStatsDataDto { [SerializeField] private int[] _attackDamage; [SerializeField] private float[] _attackSpeed; public TowerStatsData ToDomain() => new() { AttackDamage = _attackDamage, AttackSpeed = _attackSpeed }; } ``` ### 7.3 Sprite 引用 ```csharp // L0: 使用资源路径而非 Sprite 引用 public class TowerSelectItemRawData { public string IconPath { get; set; } // "UI/Icons/TowerIcon" } // L1: Controller 负责路径到 Sprite 的解析 public class CombatSelectFormController { private SpriteCacheComponent _spriteCache; private TowerSelectItemContext BuildContext(TowerSelectItemRawData raw) { return new TowerSelectItemContext { Icon = _spriteCache.GetSprite(raw.IconPath) }; } } ``` --- ## 8. 迁移顺序 ### Phase 1: 基础设施搭建 | 任务 | 说明 | |------|------| | 创建 L0 项目,引用 GameFramework.dll | 验证基础依赖 | | 验证 GameFramework Event/Fsm/ObjectPool 可用 | 核心模块连通性测试 | | 创建 L1 基础结构 | Unity Component 基类、GameFramework 适配器 | ### Phase 2: 核心业务迁移(低风险优先) | 迁移项 | 说明 | 依赖 | |--------|------|------| | `Definition/Enum/*` | 枚举类型 | 无 | | `Definition/Constant/*` | 常量定义 | 无 | | `UI/*/RawData/*` | 原始数据 | 无 | | `UI/*/Context/*` | 上下文 | 无 | | `Utility/*` | 工具类 | 无 | ### Phase 3: 业务域迁移 | 迁移项 | 说明 | 依赖 | |--------|------|------| | `InventoryGeneration/*` | 掉落、商店、奖励 | Phase 1-2 | | `PlayerInventory/*` | 背包、交易、组装 | Phase 1-2 | | `UI/*/UseCase/*` | 用例 | Phase 2 + Sprite 路径化 | | `Definition/Tag/*` | Tag 系统 | Phase 1-2 | ### Phase 4: 战斗域(核心难点) | 迁移项 | 说明 | 依赖 | |--------|------|------| | `CombatNode/CombatScheduler` | 状态机 | GameFramework.Fsm | | `CombatNode/EnemyManager/*` | 敌人域 | GameFramework.ObjectPool | | `CombatNode/CombatRunResourceStore` | 资源存储 | GameFramework.Event | | `CombatNode/CombatSettlementCalculator` | 结算 | Phase 3 | ### Phase 5: 胶水和表现层迁移 | 迁移项 | 说明 | |--------|------| | `CustomComponent/*Component` | Unity Component | | `UI/Base/*` | Controller 基类 | | `UI/*/Controller/*` | Controller 实现 | | `UI/*/View/*` | View 实现 | | `Entity/EntityLogic/*` | Entity 实现 | --- ## 9. 项目文件组织 ### 9.1 L0 项目文件 ```xml netstandard2.1 9.0 enable GeometryTD.Domain ..\..\Assets\GameFramework\Libraries\GameFramework.dll ``` ### 9.2 L1 项目文件 ```xml netstandard2.1 enable Unity\Editor\Data\Managed\UnityEngine\UnityEngine.dll ``` ### 9.3 Unity 资产结构 ``` Assets/ ├── GameFramework/ │ └── Libraries/ │ ├── GameFramework.dll ← L0 直接引用 │ └── GameFramework.xml ← 文档 │ ├── GameMain/ │ ├── L0/ # L0 DLL 输出 │ ├── L1/ # L1 源码或 DLL │ └── Scripts/ │ └── L2/ # L2 表现层 ``` --- ## 10. 验收标准 1. **L0 可独立编译**:不包含 UnityEngine.dll、UnityGameFramework.Runtime 引用 2. **GameFramework.dll 正确引用**:L0 可使用 Event/ObjectPool/Fsm/ReferencePool 3. **无循环依赖**:L2 → L1 → L0,单向依赖 4. **接口隔离**:L0 与 Unity 的交互通过 L1 适配器 5. **游戏流程完整**:拆分后战斗、商店、组装流程正常运行 --- ## 11. 附录:GameFramework.dll 模块清单 ``` GameFramework.dll 包含以下 19 个模块(纯 C# 实现): 配置与数据 ├── Config - 全局配置管理 ├── DataNode - 树状数据结点 ├── DataTable - 表格数据管理 └── Setting - 键值对存储 核心设施 ├── Event - 事件管理(EventPool) ├── ObjectPool - 对象池(ObjectPoolManager) ├── ReferencePool - 引用计数池 ├── Fsm - 有限状态机 └── Procedure - 流程(ProcedureBase) 资源管理 ├── Resource - 资源加载(需要 Unity 适配器) ├── Scene - 场景管理(需要 Unity 适配器) ├── Entity - 实体管理(需要 Unity 适配器) ├── UI - 界面管理(需要 Unity 适配器) └── Sound - 声音管理(需要 Unity 适配器) 网络与下载 ├── Network - Socket 长连接 ├── WebRequest - HTTP 短连接 └── Download - 文件下载 辅助模块 ├── Localization - 多语言(需要资源适配器) ├── FileSystem - 虚拟文件系统 ├── Debugger - 调试窗口 └── Utility - 通用工具类 ``` --- ## 12. 附录:当前 Unity 依赖渗透点 以下文件包含 `using UnityEngine` 或 `using UnityGameFramework.Runtime`,需要迁移: | 文件 | Unity 依赖 | 目标层 | |------|-----------|-------| | `TowerPlacementService.cs` | `GameEntry.Entity` | L1 | | `MapTopologyService.cs` | `Tilemap`, `Vector3Int` | L1 | | `CombatSelectFormUseCase.cs` | `UnityEngine.Sprite` | L0 → 路径化 | | `TowerStatsData.cs` | `[Serializable]`, `Color` | L0 → POCO + DTO | | `AttackPayload.cs` | `Vector3` | L0 → System.Numerics | | `MapEntity.cs` | `MonoBehaviour` | L1 | | `EnemyEntity.cs` | `Transform` | L2 | | `GameEntry.Builtin.cs` | `GameFrameworkComponent` | L1 |