培训机构的游戏框架
1. 悠游课堂(Siki学院)系列框架
A. RealFramework(真正的隐藏宝藏) ⭐ <300 Stars
// Siki学院的实战框架(很少人知道)
// 基于MVC + 消息中心
// 1. 消息中心(核心通信)
public class MessageCenter : Singleton<MessageCenter> {
private Dictionary<string, Delegate> messageDict = new Dictionary<string, Delegate>();
// 无参消息
public void AddListener(string msgName, Action callback) {
if (!messageDict.ContainsKey(msgName)) {
messageDict[msgName] = null;
}
messageDict[msgName] = (Action)messageDict[msgName] + callback;
}
// 带参消息
public void AddListener<T>(string msgName, Action<T> callback) {
if (!messageDict.ContainsKey(msgName)) {
messageDict[msgName] = null;
}
messageDict[msgName] = (Action<T>)messageDict[msgName] + callback;
}
// 广播消息
public void Broadcast(string msgName) {
if (messageDict.TryGetValue(msgName, out Delegate d)) {
(d as Action)?.Invoke();
}
}
public void Broadcast<T>(string msgName, T arg) {
if (messageDict.TryGetValue(msgName, out Delegate d)) {
(d as Action<T>)?.Invoke(arg);
}
}
// 移除监听
public void RemoveListener(string msgName, Action callback) {
if (messageDict.ContainsKey(msgName)) {
messageDict[msgName] = (Action)messageDict[msgName] - callback;
}
}
}
// 2. MVC架构实现
// Model
public class PlayerModel : Singleton<PlayerModel> {
private int level;
private int exp;
public int Level {
get { return level; }
set {
level = value;
// 通知View更新
MessageCenter.Instance.Broadcast("OnLevelChanged", level);
}
}
public void AddExp(int amount) {
exp += amount;
if (exp >= GetExpNeeded()) {
Level++;
exp = 0;
}
MessageCenter.Instance.Broadcast("OnExpChanged", exp);
}
int GetExpNeeded() => level * 100;
}
// View
public class PlayerView : MonoBehaviour {
public Text levelText;
public Slider expSlider;
void Start() {
// 注册监听
MessageCenter.Instance.AddListener<int>("OnLevelChanged", OnLevelChanged);
MessageCenter.Instance.AddListener<int>("OnExpChanged", OnExpChanged);
}
void OnDestroy() {
MessageCenter.Instance.RemoveListener<int>("OnLevelChanged", OnLevelChanged);
MessageCenter.Instance.RemoveListener<int>("OnExpChanged", OnExpChanged);
}
void OnLevelChanged(int level) {
levelText.text = $"Level {level}";
}
void OnExpChanged(int exp) {
expSlider.value = (float)exp / (PlayerModel.Instance.Level * 100);
}
}
// Controller
public class PlayerController {
public void KillEnemy() {
PlayerModel.Instance.AddExp(50);
}
}
// 3. UI管理系统
public class UIManager : MonoSingleton<UIManager> {
private Dictionary<string, GameObject> uiDict = new Dictionary<string, GameObject>();
private Stack<GameObject> uiStack = new Stack<GameObject>();
public GameObject ShowUI(string uiName) {
GameObject ui;
if (uiDict.ContainsKey(uiName)) {
ui = uiDict[uiName];
} else {
ui = Resources.Load<GameObject>($"UI/{uiName}");
ui = Instantiate(ui, transform);
uiDict[uiName] = ui;
}
// 隐藏栈顶UI
if (uiStack.Count > 0) {
uiStack.Peek().SetActive(false);
}
uiStack.Push(ui);
ui.SetActive(true);
return ui;
}
public void HideUI() {
if (uiStack.Count > 0) {
GameObject ui = uiStack.Pop();
ui.SetActive(false);
// 显示上一个UI
if (uiStack.Count > 0) {
uiStack.Peek().SetActive(true);
}
}
}
}
// 4. 音频管理
public class AudioManager : MonoSingleton<AudioManager> {
private AudioSource bgmSource;
private AudioSource sfxSource;
private Dictionary<string, AudioClip> audioDict = new Dictionary<string, AudioClip>();
protected override void Awake() {
base.Awake();
bgmSource = gameObject.AddComponent<AudioSource>();
bgmSource.loop = true;
sfxSource = gameObject.AddComponent<AudioSource>();
}
public void PlayBGM(string bgmName) {
AudioClip clip = LoadAudio(bgmName);
if (clip != null) {
bgmSource.clip = clip;
bgmSource.Play();
}
}
public void PlaySFX(string sfxName) {
AudioClip clip = LoadAudio(sfxName);
if (clip != null) {
sfxSource.PlayOneShot(clip);
}
}
AudioClip LoadAudio(string name) {
if (!audioDict.ContainsKey(name)) {
audioDict[name] = Resources.Load<AudioClip>($"Audio/{name}");
}
return audioDict[name];
}
}
// ⭐ 悠游课堂特色:
// - 教学向,代码清晰
// - 适合学习和改造
// - 实战案例丰富
// - 没有过度设计
获取方式: Siki学院付费课程、或早期GitHub仓库
B. MFramework(悠游改进版)
// 基于观察者模式的改进框架
public class MFramework {
// 事件管理器(改进版)
public class EventManager : Singleton<EventManager> {
private Dictionary<Type, Delegate> eventDict = new Dictionary<Type, Delegate>();
public void AddListener<T>(Action<T> listener) where T : struct {
Type eventType = typeof(T);
if (!eventDict.ContainsKey(eventType)) {
eventDict[eventType] = null;
}
eventDict[eventType] = Delegate.Combine(eventDict[eventType], listener);
}
public void Trigger<T>(T eventData) where T : struct {
Type eventType = typeof(T);
if (eventDict.TryGetValue(eventType, out Delegate d)) {
(d as Action<T>)?.Invoke(eventData);
}
}
public void RemoveListener<T>(Action<T> listener) where T : struct {
Type eventType = typeof(T);
if (eventDict.ContainsKey(eventType)) {
eventDict[eventType] = Delegate.Remove(eventDict[eventType], listener);
}
}
}
// 使用
public struct PlayerDeadEvent {
public int PlayerId;
public Vector3 Position;
}
void Example() {
EventManager.Instance.AddListener<PlayerDeadEvent>(OnPlayerDead);
EventManager.Instance.Trigger(new PlayerDeadEvent { PlayerId = 1 });
}
void OnPlayerDead(PlayerDeadEvent e) {
Debug.Log($"玩家{e.PlayerId}死亡");
}
}
2. 培训机构/个人大神的隐藏框架
A. 麦扣框架(小众但实用) ⭐ 内部流传
// 麦扣老师的框架(QQ群内流传)
namespace MKFramework {
// 单例模板(自动创建GameObject)
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour {
private static T instance;
public static T Instance {
get {
if (instance == null) {
GameObject go = new GameObject(typeof(T).Name);
instance = go.AddComponent<T>();
DontDestroyOnLoad(go);
}
return instance;
}
}
}
// 对象池系统
public class PoolManager : MonoSingleton<PoolManager> {
private Dictionary<string, Queue<GameObject>> poolDict = new Dictionary<string, Queue<GameObject>>();
public GameObject GetObject(string poolName, GameObject prefab) {
GameObject obj;
if (poolDict.ContainsKey(poolName) && poolDict[poolName].Count > 0) {
obj = poolDict[poolName].Dequeue();
} else {
obj = Instantiate(prefab);
obj.name = poolName;
}
obj.SetActive(true);
return obj;
}
public void PushObject(string poolName, GameObject obj) {
if (!poolDict.ContainsKey(poolName)) {
poolDict[poolName] = new Queue<GameObject>();
}
poolDict[poolName].Enqueue(obj);
obj.SetActive(false);
obj.transform.SetParent(transform);
}
}
// 延迟任务系统
public class DelayTask : MonoSingleton<DelayTask> {
public void Delay(float time, Action callback) {
StartCoroutine(DelayCoroutine(time, callback));
}
IEnumerator DelayCoroutine(float time, Action callback) {
yield return new WaitForSeconds(time);
callback?.Invoke();
}
public void FrameDelay(int frameCount, Action callback) {
StartCoroutine(FrameDelayCoroutine(frameCount, callback));
}
IEnumerator FrameDelayCoroutine(int frameCount, Action callback) {
for (int i = 0; i < frameCount; i++) {
yield return null;
}
callback?.Invoke();
}
}
}
B. 独立游戏作者的框架
- TinyFramework ⭐ 个人作品
// 极简但完整的框架
namespace TinyFramework {
// 场景状态机
public class SceneStateMachine : MonoSingleton<SceneStateMachine> {
private Dictionary<string, ISceneState> states = new Dictionary<string, ISceneState>();
private ISceneState currentState;
public void RegisterState(string name, ISceneState state) {
if (!states.ContainsKey(name)) {
states[name] = state;
}
}
public void ChangeState(string stateName) {
if (states.TryGetValue(stateName, out ISceneState newState)) {
currentState?.OnExit();
currentState = newState;
currentState.OnEnter();
}
}
void Update() {
currentState?.OnUpdate();
}
}
public interface ISceneState {
void OnEnter();
void OnUpdate();
void OnExit();
}
// 实现
public class MenuState : ISceneState {
public void OnEnter() {
Debug.Log("进入菜单");
}
public void OnUpdate() {
if (Input.GetKeyDown(KeyCode.Space)) {
SceneStateMachine.Instance.ChangeState("Game");
}
}
public void OnExit() {
Debug.Log("离开菜单");
}
}
}
3. 国外小众顶级框架
A. StrangeIoC ⭐ 1.5K Stars(被低估)
// 国外IoC框架,很少人用但很强大
using strange.extensions.context.impl;
using strange.extensions.command.impl;
using strange.extensions.mediation.impl;
// Context(类似Application)
public class GameContext : MVCSContext {
public GameContext() : base(ContextView.Instance) { }
protected override void mapBindings() {
// 绑定Command
commandBinder.Bind(GameEvent.START_GAME)
.To<StartGameCommand>();
// 绑定Model
injectionBinder.Bind<IPlayerModel>()
.To<PlayerModel>()
.ToSingleton();
// 绑定Service
injectionBinder.Bind<INetworkService>()
.To<NetworkService>()
.ToSingleton();
// 绑定Mediator(View的控制器)
mediationBinder.Bind<PlayerView>()
.To<PlayerMediator>();
}
}
// Mediator(View层的Presenter)
public class PlayerMediator : Mediator {
[Inject]
public PlayerView view { get; set; }
[Inject]
public IPlayerModel model { get; set; }
public override void OnRegister() {
// 监听View事件
view.AttackButtonClicked += OnAttackClicked;
// 监听Model变化
model.HealthChanged += OnHealthChanged;
}
void OnAttackClicked() {
// 触发Command
dispatcher.Dispatch(GameEvent.PLAYER_ATTACK);
}
void OnHealthChanged(int health) {
view.UpdateHealth(health);
}
}
// Command(业务逻辑)
public class StartGameCommand : Command {
[Inject]
public IPlayerModel playerModel { get; set; }
[Inject]
public IGameService gameService { get; set; }
public override void Execute() {
playerModel.Reset();
gameService.StartGame();
}
}
// 🌟 特点:
// - 完整的MVCS架构
// - IoC容器强大
// - 信号系统(Signal)
// - 适合大型项目
// - 学习曲线陡峭(所以小众)
GitHub: https://github.com/strangeioc/strangeioc
B. Fungus ⭐ 1.6K Stars(可视化剧情)
// 隐藏的可视化叙事框架
using Fungus;
public class FungusExample : MonoBehaviour {
public Flowchart flowchart;
void Start() {
// 执行特定Block
flowchart.ExecuteBlock("StartGame");
// 设置变量
flowchart.SetIntegerVariable("PlayerLevel", 10);
// 获取变量
int health = flowchart.GetIntegerVariable("Health");
}
// 从C#触发剧情
public void TriggerEvent() {
flowchart.SendFungusMessage("OnBossDead");
}
}
// 可视化编辑器(类似UE蓝图)
// - 对话系统
// - 分支剧情
// - 角色动画
// - 音效控制
// 全都可视化编辑
// 🎨 用途:
// - AVG游戏
// - RPG对话
// - 教学游戏
// - 互动故事
GitHub: https://github.com/snozbot/fungus
4. 来自实际项目的隐藏框架
A. UniFramework ⭐ 600+ Stars(新秀)
// 模块化框架,正在崛起
using UniFramework.Machine;
using UniFramework.Event;
using UniFramework.Singleton;
// 状态机系统
public enum GameState {
Boot,
Login,
Main,
Battle
}
public class GameStateMachine {
private StateMachine<GameState> fsm;
public void Initialize() {
fsm = new StateMachine<GameState>(this);
fsm.AddNode<BootState>(GameState.Boot);
fsm.AddNode<LoginState>(GameState.Login);
fsm.AddNode<MainState>(GameState.Main);
fsm.AddNode<BattleState>(GameState.Battle);
fsm.Run(GameState.Boot);
}
public void ChangeState(GameState state) {
fsm.ChangeState(state);
}
}
public class BootState : IStateNode<GameState> {
public void OnCreate(StateMachine<GameState> machine) {
Debug.Log("创建Boot状态");
}
public void OnEnter() {
Debug.Log("进入Boot状态");
// 加载资源、初始化系统
}
public void OnUpdate() { }
public void OnExit() {
Debug.Log("离开Boot状态");
}
}
// 事件系统
public class EventExample {
void Start() {
// 订阅事件
UniEvent.AddListener<PlayerDeadEvent>(OnPlayerDead);
}
void OnPlayerDead(PlayerDeadEvent e) {
Debug.Log($"玩家死亡: {e.PlayerId}");
}
void TriggerEvent() {
UniEvent.SendMessage(new PlayerDeadEvent { PlayerId = 1 });
}
}
// 🚀 特点:
// - 轻量级
// - 模块化
// - 易扩展
// - 文档完善
GitHub: https://github.com/gmhevinci/UniFramework
B. BDFramework ⭐ 600+ Stars
// 从实际项目提取的框架
using BDFramework.Core;
using BDFramework.UI;
using BDFramework.ResourceMgr;
public class GameStart : MonoBehaviour {
void Start() {
// 初始化框架
BDLauncher.Init();
// 加载UI
UIManager.Inst.LoadWindow<MainWindow>();
// 加载资源
var sprite = BResources.Load<Sprite>("icon_001");
}
}
// UI基类
public class MainWindow : AWindow {
[TransformPath("Button_Start")]
private Button startButton;
public override void Init() {
base.Init();
// 自动绑定
startButton.onClick.AddListener(OnStartClick);
}
void OnStartClick() {
// 打开其他UI
UIManager.Inst.LoadWindow<BattleWindow>();
}
}
// 🎮 特点:
// - ILRuntime热更新
// - Excel导表工具
// - AssetBundle管理
// - 完整工作流
GitHub: https://github.com/yimengfan/BDFramework.Core
5. 顶级隐藏的企业内部框架(部分开源/泄露)
A. NKGMobaBasedOnET ⭐ MOBA框架
// 基于ET的MOBA游戏框架
// 网咖级MOBA的完整实现
// 技能系统
[ObjectSystem]
public class SkillAwakeSystem : AwakeSystem<SkillComponent> {
public override void Awake(SkillComponent self) {
self.Skills = new Dictionary<int, Skill>();
}
}
public static class SkillComponentSystem {
public static void LearnSkill(this SkillComponent self, int skillId) {
var config = SkillConfigCategory.Instance.Get(skillId);
var skill = self.AddChild<Skill>();
skill.SkillId = skillId;
skill.Level = 1;
self.Skills[skillId] = skill;
}
public static async ETTask CastSkill(this SkillComponent self, int skillId, Vector3 targetPos) {
if (!self.Skills.TryGetValue(skillId, out Skill skill)) {
return;
}
if (!skill.CanCast()) {
return;
}
// 播放施法动画
await skill.PlayCastAnimation();
// 执行技能效果
skill.Execute(targetPos);
// 进入冷却
skill.StartCooldown();
}
}
// Buff系统
public class BuffComponent : Entity {
public Dictionary<int, Buff> Buffs;
public void AddBuff(int buffId, long casterId) {
var config = BuffConfigCategory.Instance.Get(buffId);
var buff = AddChild<Buff>();
buff.BuffId = buffId;
buff.CasterId = casterId;
buff.StartTime = TimeHelper.Now();
Buffs[buffId] = buff;
}
}
// 🎮 包含:
// - 完整MOBA系统
// - 技能、Buff、物品
// - 战斗逻辑
// - 帧同步
GitHub: https://github.com/wqaetly/NKGMobaBasedOnET
💎 真正的秘密
大厂的真相:
- 大部分大厂不用开源框架
- 都是基于小众框架改造
- 借鉴思想而不是直接用
- 教学框架往往更适合学习底层
最佳学习路径:
- 学习小众框架(理解架构思想)
- 研究大厂开源片段(学习工程化)
- 看视频教程(了解实战经验)
- 魔改成自己的(形成自己的框架)
🎯 我的建议
如果你想深入学习:
- 先看Siki的框架教程(基础扎实)
- 研究Loxodon/CatLib(学习设计模式)
- 阅读ET Framework源码(理解网络游戏)
- 最后自己实现一套(融会贯通)
如果你想快速开发:
- QFramework(快速上手)
- UniFramework(现代化)
- HybridCLR(热更新必备)
✨随便写写
by ONE
Unity游戏框架深度解析
1167

被折叠的 条评论
为什么被折叠?



