☰
Game Framework 内核解析:基于 Unity 的 19 大内置模块全景指南
2026/10/15 15:39:11 网站建设 项目流程
  • 游戏开发

【免费下载链接】GameFramework

This is literally a game framework, based on Unity game engine. It encapsulates commonly used game modules during development, and, to a large degree, standardises the process, enhances the development speed and ensures the product quality.

项目地址:https://gitcode.com/gh_mirrors/ga/GameFramework
点击查看免费下载

本篇技术指南以 Game Framework 官方简介与模块清单为核心,结合仓库源码逐一剖析其 19 个内置模块的职责边界、关键接口与实现原理。读完本文,你将理解每个模块在游戏开发中的典型应用场景、如何通过统一的模块机制获取与轮询模块、以及事件、对象池、任务池、资源异步加载等底层设施是如何支撑起这套框架的。

Game Framework 是什么

Game Framework 是一个基于 Unity 引擎的游戏框架,主要对游戏开发过程中常用模块进行了封装,很大程度地规范开发过程、加快开发速度并保证产品质量。框架不依赖具体业务逻辑,而是以"模块 + 辅助器(Helper)"的开放架构,让开发者针对自己的项目实现各模块的辅助器来适配引擎细节。

在当前仓库中,框架本体全部代码位于 GameFramework 目录下,是一个编译为类库(Library)的 C# 工程(见 GameFramework.csproj,目标框架为 .NET 3.5,AllowUnsafeBlocks已开启以支持序列化等底层操作)。README.md(即本文所依据的官方简介文档)声明当前版本内置19 个模块,下文将逐一展开。

框架的运行底座:模块注册、获取与轮询

在逐个认识 19 个模块之前,先理解框架整体的"模块化"运转方式,这有助于后续快速上手任何模块。

所有模块都继承自内部抽象类 GameFrameworkModule,它定义了三个要素:

  • Priority(优先级):优先级较高的模块会优先轮询,关闭操作会后进行;
  • Update(elapseSeconds, realElapseSeconds):每帧由框架入口统一驱动轮询;
  • Shutdown():关闭并清理模块资源。

框架入口 GameFrameworkEntry 使用一个GameFrameworkLinkedList<GameFrameworkModule>按优先级维护全部模块实例,并提供三个静态入口:

  • Update(elapseSeconds, realElapseSeconds):逐模块调用Update,完成每帧逻辑驱动;
  • Shutdown():逆序关闭所有模块、清空引用池、释放缓存的非托管内存并重置日志辅助器;
  • GetModule<T>():按接口类型获取模块。其内部通过命名约定把接口IFooManager映射为具体实现类FooManager,若模块不存在则Activator.CreateInstance自动创建并按优先级插入链表。注意它要求传入的必须是GameFramework.命名空间下的接口,否则抛出GameFrameworkException。

因此实际开发中,获取任意模块的惯用法是:

IEventManager eventManager = GameFrameworkEntry.GetModule<IEventManager>();

框架还提供一批与模块解耦的通用基础设施,包括 事件池 EventPool、引用池 ReferencePool、任务池 TaskPool、多字典与链表容器、通用变量 Variable 以及 实用函数集 Utility(涵盖程序集、压缩、转换、加密、JSON、Marshal、路径、随机、文本、CRC32 校验等工具方法),这些设施会被下文多个模块复用。

19 个内置模块逐一解析

1. 全局配置(Config)

用于存储一些全局的只读游戏配置,如玩家初始速度、游戏初始音量等。实际实现 ConfigManager 内部以Dictionary<string, ConfigData>保存配置项,并借助基座层的DataProvider<IConfigManager>统一完成数据的异步读取,因此暴露了ReadDataSuccess、ReadDataFailure、ReadDataUpdate、ReadDataDependencyAsset四个读取事件。框架本身不实现具体文件格式的解析,解析逻辑由实现 IConfigHelper 的辅助器决定——这也是 Game Framework 各模块统一的"管理器管流程、辅助器管平台细节"设计。

2. 数据结点(Data Node)

将任意类型的数据以树状结构保存,用于管理游戏运行时的各种数据。DataNodeManager 维护一棵根结点(<Root>),路径支持.、/、\三种分隔符(见PathSplitSeparator)。典型用法:

IDataNodeManager dataNodeManager = GameFrameworkEntry.GetModule<IDataNodeManager>(); // 设置/获取数据(数据以 Variable 泛型包装) dataNodeManager.SetData<VarInt>("Player.Level", 10); VarInt level = dataNodeManager.GetData<VarInt>("Player.Level");

数据结点本身也实现引用池回收(Shutdown时通过ReferencePool.Release释放根结点),体现了框架"所有可复用对象尽量进引用池"的取向。

3. 数据表(Data Table)

可以将游戏数据以表格(如 Microsoft Excel)的形式进行配置后使用,数据表的格式可以自定义。DataTableManager 通过IDataTableHelper将自定义格式的文本/二进制解析为强类型的数据行(行对象实现 IDataRow),并同样借助DataProvider<DataTableBase>异步加载。开发者需要做的事情是:为每张表定义一个实现IDataRow的行类型,并提供解析该表格式的IDataTableHelper。与 Config 类似,数据表也提供成功/失败/更新/依赖资源四类读取事件。

4. 调试器(Debugger)

当游戏在 Unity 编辑器中运行或者以 Development 方式发布运行时,将出现调试器窗口,便于查看运行时日志、调试信息等。DebuggerManager 通过ActiveWindow控制窗口显隐,以DebuggerWindowGroup树(见 DebuggerManager.DebuggerWindowGroup.cs)组织各调试窗口,开发者可以通过实现 IDebuggerWindow 把自己的调试面板注册进窗口树中。

5. 下载(Download)

提供下载文件的功能,支持断点续传,并可指定允许几个下载器进行同时下载;更新资源时会主动调用此模块。DownloadManager 基于任务池TaskPool<DownloadTask>调度下载任务,其关键参数与默认值(源码可见)包括:

参数含义默认值
FlushSize将缓冲区写入磁盘的临界大小1 MB
Timeout下载超时时长(秒)30 秒
Paused是否暂停全部下载false
任务优先级下载任务默认优先级0(见 Download/Constant.cs)

通过TotalAgentCount、FreeAgentCount、WorkingAgentCount、WaitingTaskCount可以实时观察下载队列状态。模块优先级为 5(见源码Priority重写),保证在资源更新流程中获得合理的轮询次序。

6. 实体(Entity)

将游戏场景中动态创建的一切物体定义为实体。此模块提供管理实体和实体组的功能,如显示隐藏实体、挂接实体(如挂接武器、坐骑,或者抓起另一个实体)等;实体使用结束后可以不立刻销毁,从而等待下一次重新使用。EntityManager 通过EntityInfo记录实体状态,用对象池(IObjectPoolManager)缓存实体实例对象,加载实体资源统一走LoadAssetCallbacks异步回调。实体逻辑类实现 IEntity,平台实例化等细节由 IEntityHelper 提供。同时暴露ShowEntitySuccess/Failure/Update/DependencyAsset与HideEntityComplete五个事件。

7. 事件(Event)

游戏逻辑监听、抛出事件的机制。Game Framework 中的很多模块在完成操作后都会抛出内置事件,监听这些事件将大大解除游戏逻辑之间的耦合;用户也可以定义自己的游戏逻辑事件。EventManager 直接建立在EventPool之上,构造时采用AllowNoHandler | AllowMultiHandler模式(允许无处理器、允许多处理器)。其接口(见 IEventManager)提供:

  • Subscribe(id, handler)/Unsubscribe(id, handler):订阅与取消订阅,事件 id 由事件类类型生成;
  • Fire(sender, e):抛出事件(线程安全,非主线程抛出也会保证在主线程下一帧分发);
  • FireNow(sender, e):立即分发事件(非线程安全,立刻回调)。

自定义事件的推荐做法是派生 GameEventArgs(它继承自BaseEventArgs并实现引用池接口),在事件类中实现Clear()与Id属性。

8. 文件系统(File System)

虚拟文件系统使用类似磁盘的概念对零散文件进行集中管理,优化资源加载时产生的内存分配,甚至可以对资源进行局部片段加载,极大提升资源加载性能。FileSystemManager 负责文件系统的创建、加载与销毁;具体读写由 FileSystem 实现,它包含头部数据(HeaderData)、块数据(BlockData)与字符串数据(StringData)三类内部结构,底层通过 FileSystemStream(及其通用实现 CommonFileSystemStream)访问物理文件,访问模式由 FileSystemAccess 枚举控制(Read/Write/ReadWrite)。

9. 有限状态机(FSM)

提供创建、使用和销毁有限状态机的功能,适用于状态机机制的游戏逻辑。FsmManager 以Dictionary<TypeNamePair, FsmBase>维护所有状态机,轮询时先拷贝到临时列表再逐个Update,规避遍历中销毁状态机的问题。状态机本身为 Fsm,状态基类为 FsmState,其中定义了进入(OnEnter)、轮询(OnUpdate)、离开(OnLeave)与销毁(OnDestroy)四个钩子。FSM 模块优先级为 1,是流程模块(见第 13 节)的直接依赖。

10. 本地化(Localization)

提供本地化功能,即多语言支持。Game Framework 的本地化不但支持文本,还支持任意资源的本地化——例如烟花特效可以做成多语言版本,中文版显示"新年好",英文版显示"Happy New Year"。LocalizationManager 内部维护Dictionary<string, string>字典,通过Language属性设置当前语言(枚举见 Language,初始为Unspecified,设为该值会抛异常),SystemLanguage则交给 ILocalizationHelper 获取系统语言。文本表的加载同样基于DataProvider<ILocalizationManager>,并暴露成功/失败/更新/依赖资源事件。

11. 网络(Network)

提供使用 Socket 长连接的功能,当前支持 TCP 协议,同时兼容 IPv4 和 IPv6。NetworkManager 通过Dictionary<string, NetworkChannelBase>维护多个网络频道,可同时建立多个连接与多个服务器通信(例如同时连接游戏服务器与语音服务器)。关键类型:

  • ServiceType:Tcp与TcpWithSyncReceive(同步接收的 TCP)两种频道实现分别见 NetworkManager.TcpNetworkChannel.cs 与 NetworkManager.TcpWithSyncReceiveNetworkChannel.cs;
  • AddressFamily:Unknown/IPv4/IPv6;
  • Packet:消息包基类,如果接入 ProtoBuf 之类的协议库,只要派生自 Packet 类并实现自己的消息包类即可使用;消息包的编解码与注册由 IPacketHeader 与 IPacketHandler 定义。

频道提供NetworkConnected、NetworkClosed、NetworkMissHeartBeat(心跳丢失)、NetworkError、NetworkCustomError五类事件。

12. 对象池(Object Pool)

提供对象缓存池的功能,避免频繁地创建和销毁各种游戏对象,提高游戏性能。Game Framework 自身大量使用对象池,用户也可以很方便地创建和管理自己的对象池。ObjectPoolManager 以Dictionary<TypeNamePair, ObjectPoolBase>管理全部对象池,默认参数见源码常量:

参数默认值
容量Capacityint.MaxValue
过期时间ExpireTimefloat.MaxValue(不过期)
优先级Priority0

对象池中每个对象继承 ObjectBase,释放策略可自定义(ReleaseObjectFilterCallback)。对象池模块优先级为 6,每帧负责驱动所有池的自动释放与过期处理。

13. 流程(Procedure)

流程是贯穿游戏运行时整个生命周期的有限状态机。通过流程将不同的游戏状态解耦:对于网络游戏,可能需要检查资源流程、更新资源流程、检查服务器列表流程、选择服务器流程、登录服务器流程、创建角色流程等;对于单机游戏,则需要在游戏选择菜单流程和实际玩法流程之间切换。ProcedureManager 本质上是对 FSM 的封装——Initialize(IFsmManager, params ProcedureBase[])将流程数组创建为一个状态机,StartProcedure<T>()切换当前流程,CurrentProcedure与CurrentProcedureTime分别取得当前流程与其持续时间。增加流程只需派生 ProcedureBase 并实现自己的流程类,例如:

public sealed class ProcedureMenu : ProcedureBase { protected override void OnEnter(IFsm<IProcedureManager> procedureOwner) { base.OnEnter(procedureOwner); // 进入主菜单:加载主菜单界面、播放背景音乐等 } protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds, float realElapseSeconds) { base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds); // 处理菜单逻辑,需要时切换到其他流程 } }

流程模块优先级为 -2,是所有模块中最早轮询的一批,确保游戏状态机先于其他业务运转。

14. 资源(Resource)

为保证玩家体验,框架不推荐使用同步方式加载资源,由于自身使用了一套完整的异步加载资源体系,因此只提供异步加载资源的接口。不论简单的数据表、本地化字典,还是复杂的实体、场景、界面,都使用异步加载。同时提供默认的内存管理策略(也可以自定义),多数情况下使用 GameObject 时甚至不需要自行调用Instantiate或Destroy。IResourceManager 定义了完整的能力面:

  • 资源分区:ReadOnlyPath(只读区,通常为包内资源)、ReadWritePath(读写区,通常为可更新目录)、CurrentVariant(当前变体);
  • 资源模式 ResourceMode:Package(单机模式)、Updatable(预下载的可更新模式)、UpdatableWhilePlaying(使用时下载的可更新模式);
  • 版本信息:ApplicableGameVersion(适用游戏版本号)、InternalResourceVersion(内部资源版本号)、AssetCount、ResourceCount;
  • 序列化器:PackageVersionListSerializer、UpdatableVersionListSerializer、ReadOnlyVersionListSerializer、ReadWriteVersionListSerializer、ResourcePackVersionListSerializer,分别对应单机/可更新/本地/资源包场景下的版本资源列表解析;
  • 加载能力:资源加载、二进制加载、场景加载均以回调组(如LoadAssetCallbacks、LoadSceneCallbacks、LoadBinaryCallbacks)异步返回结果。

从源码结构看,资源模块内部被拆分为资源检查(ResourceChecker)、初始化(ResourceIniter)、更新(ResourceUpdater)、校验(ResourceVerifier)、加载(ResourceLoader)以及版本列表处理(VersionListProcessor)等若干子组件,并复用下载模块完成热更新文件的拉取。这是整个框架中最庞大、最核心的模块。

15. 场景(Scene)

提供场景管理功能,可以同时加载多个场景,也可以随时卸载任何一个场景,从而很容易实现场景的分部加载。SceneManager 内部维护三个列表分别记录已加载、加载中、卸载中的场景资源名,加载与卸载全部经由资源模块的异步回调完成,并暴露LoadSceneSuccess/Failure/Update/DependencyAsset与UnloadSceneSuccess/Failure事件。

16. 配置(Setting)

以键值对形式存储玩家数据,对UnityEngine.PlayerPrefs进行封装,也可以将这些数据直接存储在磁盘上。SettingManager 本身不实现存储细节,而是把读写委托给 ISettingHelper(SetSettingHelper注入),因此在 Unity 平台可选用 PlayerPrefs 辅助器,在需要落盘的项目中可换用基于磁盘文件的辅助器。Shutdown()时框架会自动调用Save()持久化数据,此外还提供Load()、Save()、DeleteSetting以及按类型读写键值的一组方法。

17. 声音(Sound)

提供管理声音和声音组的功能,用户可以自定义一个声音的音量、是 2D 还是 3D 声音,甚至是直接绑定到某个实体上跟随实体移动。SoundManager 以Dictionary<string, SoundGroup>管理声音组,播放参数封装在 PlaySoundParams 中(包括音量、是否为 2D/3D、是否绑定实体等);声音资源同样经资源模块异步加载,暴露PlaySoundSuccess/Failure/Update/DependencyAsset事件。声音播放的平台细节由 ISoundHelper 与 ISoundAgentHelper 实现。

18. 界面(UI)

提供管理界面和界面组的功能,如显示隐藏界面、激活界面、改变界面层级等。不论是 Unity 内置的 uGUI 还是其它类型的 UI 插件(如 NGUI),只要派生自 UIFormLogic 类并实现自己的界面类即可使用;界面使用结束后可以不立刻销毁,从而等待下一次重新使用。UIManager 通过UIGroup组织界面层级,界面实例复用依托IObjectPool<UIFormInstanceObject>实例池(对应InstanceAutoReleaseInterval、InstanceCapacity、InstanceExpireTime、InstancePriority一组池参数),加载走LoadAssetCallbacks异步回调,并暴露OpenUIFormSuccess/Failure/Update/DependencyAsset与CloseUIFormComplete事件。

19. Web 请求(Web Request)

提供使用短连接的功能,可以用 GET 或 POST 方法向服务器发送请求并获取响应数据,可指定允许几个 Web 请求器同时请求。WebRequestManager 基于TaskPool<WebRequestTask>调度请求,默认超时 30 秒,默认任务优先级 0(见 WebRequest/Constant.cs),通过AddWebRequest系列方法发起请求,并暴露WebRequestStart/Success/Failure事件。与下载模块不同,它面向短连接场景(如登录验证、公告拉取、排行榜上报等),两者共享任务池调度模式但职责分明。

模块间的协作与典型启动流程

从源码的优先级设置(ProcedureManager = -2、DebuggerManager = -1、FsmManager = 1、SceneManager = 2、FileSystemManager = 4、DownloadManager = 5、ObjectPoolManager = 6、EventManager = 7,其余模块为默认 0)可以推断出框架每帧的轮询次序与关闭次序的设计意图:流程与调试器先行驱动全局状态,对象池与事件系统紧跟其后保证复用与消息分发,下载与文件系统等重 IO 模块居中;关闭时则逆序进行,事件系统最先收尾,避免关闭过程中产生孤立事件。

一个典型的网络游戏启动链路通常是:

  1. 通过GameFrameworkEntry.GetModule<T>()获取各管理器接口(自动创建模块);
  2. ProcedureManager.Initialize(fsmManager, procedures...)注册全部流程,StartProcedure<ProcedureLaunch>()启动首个流程;
  3. 启动流程中借助IResourceManager(ResourceMode.Updatable)检查并更新资源,更新时IDownloadManager被主动调用;
  4. 资源就绪后通过ISceneManager.LoadScene异步加载场景,通过IUIManager.OpenUIForm弹出登录界面;
  5. 游戏过程中的业务数据经IDataNodeManager管理、事件经IEventManager广播、频繁创建的对象经IObjectPoolManager复用。

如何获取与上手

当前仓库以源码形式提供框架本体,包含 GameFramework.sln 解决方案与 GameFramework.csproj 工程文件。上手方式:

  • 阅读源码:按 GameFramework 目录下的模块划分逐目录阅读,每个模块均由"管理器(内部实现)+ 接口 + 事件参数 + 辅助器接口"四类文件组成,结构非常规整;
  • 编译工程:用支持 .NET 3.5 的 MSBuild 工具链构建GameFramework.csproj得到GameFramework.dll与对应的 XML 文档文件(工程已开启DocumentationFile与TreatWarningsAsErrors);
  • 集成到 Unity:将程序集放入 Unity 项目,再为需要使用的模块编写对应辅助器实现(如IResourceHelper、IUIManager配套的 UI 逻辑基类等),并通过SetXxxHelper注入;
  • 进阶指引:README 中同时提供了中英文简介(English 部分官方标注 Coming soon),社区交流可参考其中提到的 QQ 讨论群 216332935;更完整的官方文档站为 gameframework.cn,可按需查阅。

小结

Game Framework 的价值在于把游戏开发中最高频的横切能力——配置、数据、调试、下载、实体、事件、文件系统、状态机、本地化、网络、对象池、流程、资源、场景、存档、声音、界面与网络请求——统一收敛为 19 个职责清晰、可插拔的模块,并在底层用引用池、事件池、任务池与异步资源加载体系把这些模块高效地串起来。理解每个模块的接口面与辅助器扩展点,是把它用进自己项目的关键一步;而源码中每个模块"接口 + 实现 + 事件参数 + 辅助器接口"的四件套结构,也为二次开发或替换平台实现提供了清晰的模板。

  • 游戏开发

【免费下载链接】GameFramework

This is literally a game framework, based on Unity game engine. It encapsulates commonly used game modules during development, and, to a large degree, standardises the process, enhances the development speed and ensures the product quality.

项目地址:https://gitcode.com/gh_mirrors/ga/GameFramework
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询