UFrame:面向规模化 Unity 项目的工程化框架
UFrame:面向规模化 Unity 项目的工程化框架
把“会做功能”变成“持续做对功能”。UFrame 以模块化与治理为核心,提供 UI / AI 行为树 / 网络 / 资源 / 任务编排 / 日志 / 对象池 / 定时器 / 表格配置等一系列可插拔能力,让你的项目在可维护性、性能与协作效率上稳步增长。
-
支持版本:Unity 2021.3+ / .NET Standard 2.1
-
仓库:https://github.com/zouhunter/uframe
目录
-
为什么是 UFrame
-
架构鸟瞰
-
核心框架层(Manage)
3.1 生命周期与调度总线
3.2 基于 Adapter 的“代理单例系统”(本章重点)
3.3 可观测性:优先级、间隔调度、资源自动回收 -
业务中台层
4.1 行为树(BehaviourTree)
4.2 UI 系统(BridgeUI)
4.3 网络(NetSocket)
4.4 资源(AssetBundles)
4.5 任务流(YieldFlow) -
工具与配套
TableCfg / Timer / Pool / Logs / Audio / Input / Tween -
快速开始与脚手架
-
最佳实践与团队落地
-
在 AI 生成代码时代的演进思路
-
Roadmap 与结语
1. 为什么是 UFrame
商业化 Unity 项目的主要复杂度来自工程环节:模块耦合、协作磨损、性能与质量的持续回归。UFrame 提供清晰边界 + 默认正确做法,把“经验”沉淀为“制度”:
-
分层+模块边界:可替换、可裁剪、可灰度。
-
统一调度与治理:生命周期、Update 家族、资源回收、异常护栏。
-
默认实践:对象池、热更与依赖、日志与性能计时、任务可取消。
2. 架构鸟瞰
┌───────────────────────── 应用层 (Application) ─────────────────────────┐
│ 玩法逻辑 / 关卡规则 / 战斗系统 │
├────────────────────────── UI 层 (BridgeUI) ───────────────────────────┤
│ 面板生命周期 / 数据绑定 / 事件中介 / 组与层级 / 过渡动画 │
├────────────────────── 业务中台层 (Business Logic) ────────────────────┤
│ BehaviourTree | PureMVC | YieldFlow(协程任务流) | Task │
├────────────────────────── 网络层 (NetSocket) ─────────────────────────┤
│ TCP/UDP / 序列化 / 心跳重连 / 数据包处理 │
├────────────────────────── 资源层 (AssetBundles) ──────────────────────┤
│ 打包 / 依赖 / 热更 / 版本 / 缓存策略 │
├────────────────────────── 基础层 (Foundation) ────────────────────────┤
│ Common | Logs | Timer | Pool │
├────────────────────────── 框架层 (Manage) ────────────────────────────┤
│ 生命周期治理 / 单例容器 / 适配器 / 调度总线 │
└────────────────────────────────────────────────────────────────────────┘
3. 核心框架层(Manage)
3.1 生命周期与调度总线
-
BaseGameManage:全局调度器;统一注册/注销 Agent,按优先级初始化与逆序回收。
-
Update 家族接口:
IUpdate / IFixedUpdate / ILateUpdate
+IInterval
(门闸节流)。 -
资源治理:
AdapterBase.New<T>()
创建的IDisposable
由框架统一回收。 -
异常护栏:调度层统一捕获、上报并止血。
3.2 基于 Adapter 的“代理单例系统”(重点)
把“单例”升级为带接口的服务容器,实现可继承/可替换/可测试的服务边界。
3.2.1 三种容器形态
-
Adapter<T>
:容器即实例(入门)
适合轻量模块,仍享有生命周期/优先级/资源治理。
public class GameSettings : Adapter<GameSettings>
{public float Volume { get; set; } = 1.0f;protected override void OnInitialize() => Load();protected override void OnRecover() => Save();
}
-
Adapter<T, I>
:接口隔离(标准)
容器Instance
返回接口I
,实现可返this
。
public interface IPlayerData { string Name {get;set;} }
public class PlayerData : Adapter<PlayerData, IPlayerData>, IPlayerData
{public string Name { get; set; } = "New";protected override IPlayerData CreateAgent() => this;
}
-
Adapter<T, I, Impl>
:接口+实现分离(进阶)
容器只暴露接口,真正逻辑在Impl
,天然支持“单例继承效果”。
public interface IInventory { void Add(int id,int n); }
public class InventoryImpl : AdapterBase, IInventory { /* ... */ }public class Inventory : Adapter<Inventory, IInventory, InventoryImpl>
{protected override InventoryImpl CreateAgent() => new InventoryImpl();
}
3.2.2 “单例的继承效果”三种常用策略
-
子类增强(直觉继承)
public class InventoryPro : InventoryImpl
{public override void Add(int id,int n){ base.Add(id,n); Analytics.LogAdd(id,n); }
}
public class Inventory : Adapter<Inventory, IInventory, InventoryImpl>
{protected override InventoryImpl CreateAgent()=> Application.platform==RuntimePlatform.Android ? new InventoryPro() : new InventoryImpl();
}
-
策略/装饰(组合优先)
public interface IRule { bool AllowAdd(int id,int n); }
public class RuleDefault : IRule { public bool AllowAdd(int id,int n)=>true; }
public class InventoryImpl : AdapterBase, IInventory
{private readonly IRule _rule;public InventoryImpl(IRule rule){ _rule=rule; }public void Add(int id,int n){ if(_rule.AllowAdd(id,n)){ /*...*/ } }
}
public class Inventory : Adapter<Inventory, IInventory, InventoryImpl>
{protected override InventoryImpl CreateAgent() => new InventoryImpl(new RuleDefault());
}
-
热插拔实现(运行期切换)
public abstract class HotSwapContainer<T,I,Impl> : Adapter<T,I,Impl> where T:HotSwapContainer<T,I,Impl>,new() where Impl:AdapterBase,I
{private Func<Impl> _factory;public void Use(Func<Impl> factory)=>_factory=factory;protected override Impl CreateAgent()=>_factory?.Invoke() ?? base.CreateAgent();
}
// 使用
HotSwapContainerInstance.Use(()=> new InventoryPro());
HotSwapContainerInstance.Release(); // Recover 后重建
_ = HotSwapContainerInstance.Instance; // 生效
3.2.3 可观测、可治理:优先级 / 间隔 / 资源自动回收
-
优先级:写死拓扑,解决隐式依赖;回收按逆序。
-
间隔:
Interval
是门闸,避免“每帧重活”。 -
资源:
New<T>()
统一释放,防泄漏。
public class EnemySpawner : Singleton<EnemySpawner>, IUpdate
{public override int Priority => 30;public bool Runing { get; set; } = true;public float Interval => 0.5f; // 节流public void OnUpdate(){ /* spawn */ }
}
迁移建议:把旧的
MonoBehaviour
单例抽象为IService
接口 → 把逻辑移到Impl
(AdapterBase
)→ 用Adapter<T,I,Impl>
暴露接口给外界。
3.3 可观测性实践清单
-
核心路径必须打点:初始化耗时、Update 次数/耗时、Recover 次数、内存峰值。
-
在 Editor 下输出已注册 Agent 列表(类型/优先级/Alive/接口名)。
-
对异常统一上报(含容器名、接口与调用栈)。
4. 业务中台层
4.1 行为树(BehaviourTree)
-
特性:可视化编辑、复合/装饰/叶子节点、运行态状态管理、条件/子条件、构建防裁剪。
-
建议:节点只做决策,动作落到系统(动画/导航/战斗);用黑板集中状态。
[NodePath("AI/攻击敌人")]
public class AttackEnemyNode : ActionNode
{public float range=5; public int damage=10;protected override byte OnUpdate(){ /* 找最近敌人并攻击 */ }
}
4.2 UI 系统(BridgeUI)
-
特性:面板生命周期、数据访问者、组与层级、过渡动画、自动加载/卸载。
-
规约:禁止在业务侧实例化面板,统一走
IUIFacade
;异步加载需支持取消/幂等。
4.3 网络(NetSocket)
-
特性:TCP/UDP、序列化、连接管理、心跳/重连、数据包处理器。
-
建议:协议用注解/IDL 生成 DTO;跨线程回到主线程派发;断线重连+关键数据重拉。
4.4 资源(AssetBundles)
-
特性:自动打包、依赖管理、热更、版本控制、缓存策略。
-
建议:Bundle 颗粒度按 UI/角色/场景分层;公共依赖单独包;统计命中率与峰值内存驱动拆包。
4.5 任务流(YieldFlow)
-
特性:任务依赖、并发、自动回收、可取消、状态流转。
-
建议:用声明式流程替代散落的
StartCoroutine
;切场景统一取消。
5. 工具与配套(速览)
-
TableCfg:Excel → 代码生成 → 运行时访问,类型安全/可校验。
-
Timer:延迟/周期/帧计/条件,支持时间缩放与取消。
-
Pool:统一创建/复用/回收,减少 GC 抖动。
-
Logs:分级/过滤/文件/性能计时,事故复盘材料要齐。
-
Audio / Input / Tween:工程层面的“默认实现”,可替换可裁剪。
6. 快速开始与脚手架(10 分钟)
-
克隆并导入
git clone https://github.com/zouhunter/uframe.git
将 Assets
合并到项目,检查 Package 依赖。
-
初始化框架
var game = new BaseGameManage();
game.Initialize();
-
打开首屏 UI
SingleUIFacade.Instance.Open("MainMenu");
-
跑一个最小 AI 行为树
var tree = ScriptableObject.CreateInstance<BTree>();
tree.rootTree = TreeInfo.Create();
tree.rootTree.node = new MyActionNode();
tree.StartUp();
7. 最佳实践与团队落地
-
组织:每个业务模块“三件套”——
IService
/ServiceImpl
/ServiceContainer
。 -
优先级:基础(90–100)→ 核心(50–89)→ 业务(20–49)→ UI(0–19)。
-
避免循环依赖:靠优先级写死拓扑;必要时延迟获取。
-
可取消为第一原则:场景切换/中断时,任务/计时器/加载/UI 都能“体面退出”。
-
CI:EditMode 单测 + PlayMode 冒烟;构建报告(包体、内存、纹理/网格、AB 依赖)。
红线:
-
不跨越层级访问(UI 直调网络等)。
-
不在构造函数里触碰 Unity API(放到
OnInitialize()
)。 -
不用魔法数协议;不把重活放每帧(用
Interval/Timer/YieldFlow
)。
8. 在 AI 生成代码时代的演进思路
-
边界先行:人写接口与容器(Adapter),AI 生成
Impl/节点/策略/DTO/测试脚手架
。 -
治理闭环:接口契约 + 统一调度 + 日志/计时/指标 → 生成代码可快速验证与回滚。
-
热插拔:容器层提供工厂钩子,AI 产物可灰度上线,异常即可回退到稳定实现。
框架即护栏:让 AI 帮你“批量创作”,而不是“批量制造技术债”。
9. Roadmap(社区参与欢迎 PR)
-
行为树可视化运行态仪表板(节点耗时/命中率)
-
资源系统命中率与内存峰值可视化面板
-
YieldFlow 图形化编排与可视化取消链
-
Adapter 工厂的 Editor 配置(平台/渠道/灰度开关)
结语
UFrame 不是替你做决定,而是让正确的决定更容易:
-
边界清晰(接口稳定、实现可替换)
-
治理到位(生命周期、调度、资源、异常)
-
度量先行(日志、性能、指标)
当这些工程制度固化为日常习惯,你的 Unity 项目会更快迭代、更稳上线。
-
仓库地址:https://github.com/zouhunter/uframe
-
Issue / 讨论 / PR 欢迎随时交流 🚀