一个 Unity 框架能做多少事?86 个模块 + 21 个小游戏平台

写在前面:这不是一篇产品说明书。这是我在做独立游戏这些年里,踩过的每一个坑,以及为了不再踩第二次而造的工具。

你是不是也这样

新建一个 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。

它不完美,但它是真实的。每一个模块都是在真实项目中验证过的。


相关推荐
m0_547722921 小时前
从零搭建乒乓球比赛管理系统——Spring Boot + 原生 HTML 实战
spring boot·后端·html
To_OC1 小时前
搞懂二叉树递归遍历,我居然是从爬楼梯开始的
前端·javascript·数据结构
用户637328456111 小时前
MyBatis与MyBatis-Plus区别
后端
何何____1 小时前
svg基本图形绘制介绍
前端·css
weedsfly1 小时前
Sass 运算 vs CSS calc():你的计算该放在哪一层?
前端
爆浇牛肉面1 小时前
手写消息队列(一):从零搭建Spring Boot + MyBatis + SQLite
后端
Oo_行者_oO1 小时前
Spring Schedule + ShedLock + RabbitMQ 生产级落地方案 - 云楼(中国)
java·后端
Hical611 小时前
百万 TCP 长连接内存实测:50 万点回归,R²=1.0000,每连接 7.58 KB
后端·github
Mahir081 小时前
HashMap 底层原理深度解密:从数据结构到 JDK1.7/1.8 演进全解
java·后端·面试·hashmap