# GameCore 游戏框架设计文档 ## 概述 通用 Unity 游戏框架,以 Unity Package 形式分发,基于自研轻量 DI 容器,采用核心扩展式架构。目标:跨项目可复用 + 开箱即用的常用系统。 - **目标平台:** Unity 2022 LTS - **架构模式:** 依赖注入 (DI) - **分发形式:** Unity Package - **DI 容器:** 自研轻量实现(反射,预留 Source Generator 优化接口) --- ## 架构:核心扩展式 ``` GameCore (核心 asmdef) ├── DI 容器 ├── 所有模块接口定义 └── 核心模块:事件系统、对象池、游戏流程控制、计时器 扩展包 (各自独立 asmdef,只依赖核心) ├── GameCore.UI ├── GameCore.Audio ├── GameCore.Resource ├── GameCore.Data ├── GameCore.Save └── GameCore.Network 可替换实现 (各自独立 asmdef) ├── GameCore.Defaults — 默认 EventBus + Timer ├── GameCore.R3 — R3 实现(可选替换 Defaults) ├── GameCore.Resource.Resources ├── GameCore.Resource.Addressables ├── GameCore.Save.FileStorage └── GameCore.Save.PlayerPrefsStorage ``` **设计原则:** - 核心包定义接口,不包含具体实现(DI、Pool、Lifecycle 除外) - 扩展包只依赖核心,互不依赖 - 可替换实现通过 DI Installer 注册,换实现不改上层代码 --- ## DI 容器 ### 能力 - 接口→实现绑定 (`Bind().To()`) - 实例绑定 (`ToValue(instance)`) - 生命周期:`AsSingleton()` / `AsTransient()` - 子容器(场景级作用域,子容器销毁时自动释放其单例) - 构造函数注入(普通 C# 类) - 属性注入 `[Inject]`(MonoBehaviour) - 方法注入 `[Inject]`(初始化/PostConstruct) - 自动递归解析依赖链 - 反射实现,预留 Source Generator 优化接口 ### 子容器 ```csharp // 全局容器(跨场景) var root = new GameContainer(); // 场景容器(继承全局,场景销毁时一起释放) var sceneContainer = root.CreateChild(); // 子容器可访问父容器绑定 sceneContainer.Resolve(); // 从父容器拿 // 子容器同名绑定覆盖父容器 sceneContainer.Bind().To().AsSingleton(); ``` ### 注入方式 ```csharp // 构造函数注入 — 普通 C# 类 public class AudioManager : IAudioManager { private readonly IEventBus _eventBus; public AudioManager(IEventBus eventBus) { _eventBus = eventBus; } } // 属性注入 — MonoBehaviour public class GameCoreEntry : MonoBehaviour { [Inject] private IEventBus _eventBus; } // 方法注入 — 初始化/PostConstruct public class GameManager : IGameManager { [Inject] public void Init(IEventBus eventBus, IDataManager data) { // 所有依赖就绪后执行 } } ``` --- ## 核心模块 ### 事件总线 (IEventBus) 接口定义在核心包,实现可替换。 ```csharp public interface IEventBus { void Subscribe(Action handler) where T : IEvent; void Unsubscribe(Action handler) where T : IEvent; void Publish(T evt) where T : IEvent; } ``` - 事件用 `struct`,避免 GC 压力 - 泛型事件分发,每个事件类型独立维护订阅者列表 默认实现:`GameCore.Defaults.DefaultEventBus` R3 实现:`GameCore.R3.R3EventBus` ### 计时器/调度器 (ITimerManager) 接口定义在核心包,实现可替换。 ```csharp public interface ITimerManager { ITimerHandle Delay(float seconds, Action callback); ITimerHandle Repeat(float interval, Action callback); void Tick(float deltaTime); } public interface ITimerHandle { void Cancel(); bool IsDone { get; } } ``` - 不依赖 MonoBehaviour Coroutine,纯 Tick 驱动 - 内部用对象池管理 Timer 对象 默认实现:`GameCore.Defaults.DefaultTimerManager` R3 实现:`GameCore.R3.R3TimerManager` ### 对象池 (IPoolManager) ```csharp public interface IPoolManager { IPool CreatePool(Func factory, int prewarm = 0); IGameObjectPool CreateGameObjectPool(string prefabPath, int prewarm = 0); } public interface IPool { T Get(); void Release(T item); } ``` - 泛型对象池,支持任意类型 - 预加载容量,支持预热 - GameObject 池的创建/销毁由 Resource 扩展包实现,核心只定义接口 ### 游戏流程控制 (GameLifecycle) ```csharp public static class GameCore { public static void Launch(StartupConfig config); public static void Tick(); public static void Shutdown(); } public class StartupConfig { public IInstaller[] Installers; public IStartupTask[] StartupTasks; } public interface IInstaller { void Install(IGameContainer container); } public interface IStartupTask { Task Execute(); } ``` 生命周期阶段: ``` Launch → Installers 注册绑定 → ResolveAll 创建单例 → StartupTasks 按序执行 → Running ↓ 场景切换时 子容器销毁 ↓ Shutdown ``` - `IInstaller` 统一模块注册入口 - `IStartupTask` 控制启动顺序(支持异步) - 场景切换时自动销毁场景级子容器 - Shutdown 时按反序释放所有模块 --- ## 扩展包 ### GameCore.Resource — 资源加载 ```csharp public interface IResourceLoader { T Load(string path) where T : Object; Task LoadAsync(string address) where T : Object; void Release(T asset); void ReleaseAll(); } ``` - 统一封装,支持引用计数,同一资源多次加载不重复 - 存储实现可替换:Resources / Addressables / AssetBundle / 自定义 ### GameCore.UI — UI 管理 ```csharp public interface IUIManager { T Open(string layer = null) where T : UIPanelBase; void Close() where T : UIPanelBase; void CloseAll(); void CloseLayer(string layer); void RegisterLayer(string name, Canvas canvas, int sortOrder); } public abstract class UIPanelBase : MonoBehaviour { [Inject] protected IEventBus _eventBus; [Inject] protected IResourceLoader _loader; public virtual void OnOpen() { } public virtual void OnClose() { } } ``` - 层级由用户自定义注册,不预设固定层级 - 面板栈管理,支持返回上一级 - 面板复用(配合对象池) ### GameCore.Audio — 音频管理 ```csharp public interface IAudioManager { IAudioHandle PlayBGM(string name, bool loop = true, float fadeIn = 0f); void StopBGM(float fadeOut = 0f); IAudioHandle PlaySFX(string name); void Stop(IAudioHandle handle); void Pause(IAudioHandle handle); void Resume(IAudioHandle handle); void SetBGMVolume(float volume); void SetSFXVolume(float volume); void MuteAll(); void UnmuteAll(); } public interface IAudioHandle { float Volume { get; set; } bool IsPlaying { get; } void Stop(float fadeOut = 0f); } ``` - fadeIn/fadeOut 处理音频过渡,具体曲线在实现层 - IAudioHandle 可停止单个音频 - SFX 用对象池管理 AudioSource ### GameCore.Data — 数据/配置管理 ```csharp public interface IDataManager { void RegisterParser(string format) where TParser : IDataParser; void LoadModule(string moduleName); void UnloadModule(string moduleName); bool IsModuleLoaded(string moduleName); T GetConfig(string key) where T : IConfig; IReadOnlyList GetConfigs() where T : IConfig; } public interface IDataParser { IEnumerable Parse(string content); } ``` - 格式自定义:注册 IDataParser 实现(JSON/CSV/ScriptableObject/自定义) - 分模块按需加载和卸载 ### GameCore.Save — 存档系统 ```csharp public interface ISaveManager { Task Save(string slotName, object data); Task Load(string slotName); void Delete(string slotName); bool Exists(string slotName); string[] ListSaves(); } public interface ISaveStorage { Task Write(string key, byte[] data); Task Read(string key); void Delete(string key); bool Exists(string key); } ``` - ISaveManager 负责序列化和业务逻辑 - ISaveStorage 负责底层读写,可替换:File / PlayerPrefs / 云存档 / 自定义 - 支持多存档位 ### GameCore.Network — 网络层 ```csharp public interface INetworkService { Task Request(string url, object body); Task Connect(string url); void Disconnect(); void Send(T message); void OnReceive(Action handler); } ``` - HTTP 请求封装(GET/POST) - WebSocket 长连接 - 断线重连、超时处理、心跳机制 --- ## 包结构 ``` com.yourname.gamecore/ ├── package.json ├── README.md ├── CHANGELOG.md ├── LICENSE ├── Runtime/ │ ├── GameCore/ # 核心 asmdef │ │ ├── DI/ │ │ ├── Events/IEventBus.cs │ │ ├── Timer/ITimerManager.cs │ │ ├── Pool/ │ │ ├── Lifecycle/ │ │ └── Interfaces/ │ │ │ ├── GameCore.Defaults/ # 默认 EventBus + Timer │ ├── GameCore.R3/ # R3 实现(可选) │ │ │ ├── GameCore.UI/ │ ├── GameCore.Audio/ │ │ │ ├── GameCore.Resource/ # 接口 │ ├── GameCore.Resource.Resources/ # Resources 实现 │ ├── GameCore.Resource.Addressables/ # Addressables 实现 │ │ │ ├── GameCore.Data/ │ │ │ ├── GameCore.Save/ # 接口 + 序列化 │ ├── GameCore.Save.FileStorage/ │ ├── GameCore.Save.PlayerPrefsStorage/ │ │ │ └── GameCore.Network/ │ ├── Editor/ │ └── GameCore.Editor/ └── Samples~/ ``` --- ## 完整使用示例 ```csharp // 入口 public class GameBootstrap : MonoBehaviour { void Awake() { GameCore.Launch(new StartupConfig { Installers = new IInstaller[] { new CoreInstaller(), new TimerInstaller(), new ResourceInstaller(), new AudioInstaller(), new UIInstaller(), new DataInstaller(), new SaveInstaller(), }, StartupTasks = new IStartupTask[] { new LoadConfigTask(), new ShowMainMenuTask(), } }); } void Update() => GameCore.Tick(); void OnDestroy() => GameCore.Shutdown(); } // 使用模块 public class MainMenuPanel : UIPanelBase { [Inject] private IAudioManager _audio; [Inject] private IEventBus _eventBus; [Inject] private IDataManager _data; public override void OnOpen() { _audio.PlayBGM("main_menu", fadeIn: 1f); var weapons = _data.GetConfigs(); RenderWeaponList(weapons); } public void OnStartGameClick() { _audio.PlaySFX("click"); _eventBus.Publish(new StartGameEvent { Level = 1 }); } } // 事件定义 public struct StartGameEvent : IEvent { public int Level; } ```