写在前面:这不是一篇产品说明书。这是我在做独立游戏这些年里,踩过的每一个坑,以及为了不再踩第二次而造的工具。
你是不是也这样
新建一个 Unity 工程,斗志昂扬,觉得这次一定能把游戏做完。
然后第一周,你在写全局单例。第二周,你在造事件系统。第三周,你开始封装资源加载。一个月过去了,游戏还没开始做,基础设施写了一堆,而且到处是 bug。
或者更惨------上一个项目的代码太乱了,你想在新项目里"好好设计一下",结果又从零开始搭一遍。
我做过很多次这样的事。
后来我发现,每个 Unity 项目开头要做的事情,80% 是重复的。事件系统、对象池、状态机、UI 管理、资源加载、网络通信......这些东西和你做什么游戏没关系,但你每次都要写。
GameFrameX 就是我写给自己的答案:把这些重复的事情一次性做好,让你把时间花在游戏本身上。
GameFrameX 是什么
一句话:一个 Unity 游戏框架,86 个模块化子包,按需引入,覆盖从项目启动到上线的全流程。
它不是一个强迫你全盘接受的"全家桶"。每个功能都是独立的 UPM 包,你只需要引入你用得到的部分。
支持 Unity 2019.4+,全平台(Windows / macOS / Linux / iOS / Android / WebGL),Apache 2.0 开源协议。
做一款游戏到底要做什么
我不想用功能列表来介绍这个框架。我想沿着做一款游戏的真实流程,告诉你每个环节 GameFrameX 帮你做了什么。
项目启动
每次新建项目,总有几件事绕不过去:全局入口怎么管理?组件之间的生命周期怎么协调?日志怎么打?怎么在运行时切换帧率和游戏速度?
GameFrameX 的做法是:你创建一个 GameObject,挂上 BaseComponent,框架自动完成初始化。之后所有功能模块通过 GameEntry.GetComponent<T>() 统一获取。
csharp
// 获取任何模块,就这一行
var objectPool = GameEntry.GetComponent<ObjectPoolComponent>();
框架内部采用组件-模块双层架构。组件层继承 MonoBehaviour,负责和 Unity 生命周期对接;模块层是纯 C# 类,负责业务逻辑。你要扩展功能,写一个 Module 注册进去就行。
顺便,框架还内置了这些你每次都要写、但没人想写的东西:
- 对象池(ObjectPool)--- 频繁创建销毁的东西(子弹、特效、怪物)直接从池子里拿,不用每次 new
- 引用池(ReferencePool)--- 减少 GC 分配,特别是事件参数这种高频使用的东西
- 事件池(EventPool)--- 类型安全的发布-订阅,不用手写回调地狱
- 任务池(TaskPool)--- 异步任务队列管理
- BindableProperty --- 可绑定属性,MVVM 数据绑定直接用
还有一整套扩展方法库和工具集------加密(AES / RSA / DSA)、哈希(MD5 / SHA1 / XxHash)、压缩、JSON、文件操作、ID 生成......这些每个项目都会用到但没人想自己写的东西,全都包了。
资源加载
你一开始用 Resources.Load(),觉得挺好。后来资源多了,包体炸了,你换成 AssetBundle。然后你发现 AB 的依赖关系是个噩梦------漏打一个依赖引用,运行时就是满屏粉红方块。
更惨的是要做热更新。资源服务器上放哪些版本?怎么对比差异?怎么下载?下载到一半断了怎么办?
GameFrameX 封装了一套统一的资源管理抽象层,底层对接 YooAsset。你不用关心 AB 怎么打、依赖怎么管、热更怎么判------框架帮你处理了。
针对小游戏平台,还有专门的 YooAsset 适配器(微信、支付宝、抖音、Google Play、TapTap),不同平台的资源加载差异全部屏蔽。
如果你需要从远程加载图片(比如头像、活动 banner),还有图片缓存模块,基于 MD5 校验的磁盘缓存,加载过的不用重复下载。
UI
每个 Unity 项目都要解决 UI 管理的问题。页面怎么栈式管理?打开关闭的生命周期怎么处理?UI 之间怎么通信?
GameFrameX 的 UI 模块提供了统一的抽象层,目前支持两种实现:
- UGUI --- Unity 原生 UI 方案
- FairyGUI --- 如果你更习惯编辑器可视化搭 UI
不管是哪种,页面栈管理、生命周期回调、UI 之间的事件通信这些逻辑都是统一的。换 UI 方案只换适配层,业务代码不用动。
网络
做网络游戏,你得处理长连接(TCP/UDP)、HTTP 请求、WebSocket......这些 GameFrameX 都有对应的模块。
网络模块管理连接状态、断线重连;Web 模块封装了 GET / POST / PUT / DELETE,支持异步操作;还有 WebSocket 和 WebView 组件。如果你用 Protocol Buffers,有专门的 Web.Protobuf 模块,HTTP 请求直接走 ProtoBuf 序列化,不用自己写编解码。
游戏逻辑
游戏的核心逻辑层,往往是代码最容易乱的地方。
状态机(FSM) --- 角色的待机、移动、攻击、受击......你当然可以用一坨 if-else 来写,但三个月后你自己都不想看。GameFrameX 的有限状态机支持状态转换条件和生命周期回调,把状态逻辑拆干净。
流程管理(Procedure) --- 游戏启动 → 检查更新 → 加载资源 → 主菜单 → 战斗......整个游戏流程也是状态机,只不过粒度更大。Procedure 模块就是干这个的。
事件系统(Event) --- UI 点击了"开始游戏"按钮 → 流程模块收到事件 → 切换到加载流程 → 资源模块开始加载 → 加载完成 → 切换到战斗流程。模块之间用事件通信,互相不知道对方存在,耦合度降到最低。
实体管理(Entity) --- 如果你需要管理大量的游戏实体(怪物、NPC、道具),Entity 模块提供了显示/隐藏/附加逻辑的管理机制。
场景管理(Scene) --- 场景的加载、卸载、切换,支持过渡动画。
下载管理(Download) --- 多任务队列、断点续传、实时进度追踪。热更资源下载、补丁下载都用得到。
还有协程工具、精确定时器、多语言本地化、音频管理(分组、音量控制、3D 音效)......这些都是每个游戏都需要、但每个项目都在重复造的东西。
上线:小游戏平台适配
在中国做独立游戏,你大概率绕不开小游戏平台。
问题是------每个平台的 API 都不一样。微信小游戏一套,抖音小游戏一套,支付宝小游戏又一套......你光是做平台适配就能花掉一个月。而且每个平台的资源加载方式、登录流程、广告接口都不一样。
GameFrameX 支持一键切换 21 个小游戏平台。你不需要记住每个平台的 API 差异------框架帮你屏蔽了。
编辑器菜单里点一下"启用微信小游戏",框架自动切换编译宏定义、适配资源加载路径、对接平台 API。再点一下"启用抖音小游戏",自动切过去。互斥机制确保同一时间只有一个平台生效。
21 个平台包括:
- 国内 9 个:微信、支付宝、抖音、快手、百度、京东、淘宝、美团、B站
- 国际 7 个:Discord、YouTube、Facebook、Google Play、TikTok、CrazyGames、Poki
- 厂商 4 个:华为、OPPO、vivo、小米
- 平台 1 个:TapTap
变现:广告、支付、登录
游戏做出来了,要变现。
广告 --- 框架提供了统一的广告抽象层,目前集成了穿山甲(CSJ)、TopOn 聚合、以及微信/支付宝/抖音/快手小游戏广告。切换广告平台?换一个实现包就行,业务代码不用改。
支付 --- 支付宝、Apple StoreKit、Google Play Billing、抖音小游戏支付。同样是抽象层设计,统一接口,按平台接入。
登录 --- Apple Sign-In、Facebook、Google、QQ、微信。第三方登录 SDK 的接入是最恶心的部分之一------每个平台的鉴权流程都不一样,OAuth 回调方式千奇百怪。框架把这块也统一了。
数据分析
上线了还得看数据。GameAnalytics、TalkingData、AppsFlyer、Adjust、Grafana Loki......这些分析工具的 SDK 接入方式各不相同,GameFrameX 同样做了抽象层,想接哪个就引哪个包。
其他能力
- 对象存储 --- 阿里云 OSS、七牛云、腾讯云 COS,上传下载统一接口
- 社交分享 --- ShareSDK 集成,微信/QQ/微博一键分享
- Steam --- Steamworks 成就、排行榜、云存档
- 热更新 --- 内置 HybridCLR 方案,支持 WebGL 平台;也支持 XLua 热修复
- 第三方库 --- UniTask(async/await)、DOTween(动画)、Spine(骨骼动画)、Sentry(崩溃上报)
- 调试工具 --- 运行时调试器,游戏内直接查看组件状态
- 构建工具 --- 自动化构建流水线,WebGL 专用构建,Xcode / Android 工程配置
- 配置管理 --- 运行时配置、全局远程配置、Luban 集成、ProtoBuf 序列化
为什么是 86 个包
86 个不是凑数。
每一个包背后都是一个具体的坑。有的是"这个 SDK 的接口太恶心了,我封装了一下",有的是"每次项目都要写这个东西,我提取出来了",有的是"对接小游戏平台的时候差点没被搞死"。
而且 86 个包不代表你要全部引入。框架的设计原则是按需引入------你做单机游戏,不需要网络模块;你不做小游戏,不需要平台适配;你只用 UGUI,不需要 FairyGUI。每个包都是独立的 UPM 包,各取所需。
安装
最简单的方式------Unity Package Manager,添加 Git URL:
bash
https://github.com/GameFrameX/com.gameframex.unity.git
或者用 Scoped Registry,在 Packages/manifest.json 里加一段配置,之后所有 com.gameframex.unity.* 的包都可以通过 Package Manager 直接安装:
json
{
"scopedRegistries": [
{
"name": "GameFrameX",
"url": "https://gameframex.upm.alianblank.uk",
"scopes": ["com.gameframex"]
}
],
"dependencies": {
"com.gameframex.unity": "1.10.1"
}
}
最后
如果你是一个独立游戏开发者,如果你也厌倦了每次新项目都从零开始搭基础设施,如果你也想把时间花在游戏本身而不是重复造轮子上------试试 GameFrameX。
它不完美,但它是真实的。每一个模块都是在真实项目中验证过的。
- 官方文档:gameframex.doc.alianblank.com
- GitHub:github.com/GameFrameX
- UPM Registry:gameframex.upm.alianblank.uk
- QQ 交流群:467608841