2556 字
13 分钟
游戏开发常用设计模式完全指南
系统讲解游戏开发中最常用的设计模式,包括单例模式、观察者模式、状态机模式、对象池模式、命令模式等,并结合Unity和游戏开发实战进行深入分析。
前言
设计模式是解决特定问题的最佳实践,是经过大量项目验证的代码组织方式。在游戏开发中,合理运用设计模式能让代码更清晰、更易维护、更易扩展。本文系统讲解游戏开发中最常用的设计模式。
1. 单例模式(Singleton)
概念
确保一个类只有一个实例,并提供全局访问点。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| GameManager | 游戏状态管理,全局唯一 |
| AudioManager | 音频管理,统一控制背景音乐、音效 |
| UIManager | UI 管理,协调所有界面 |
| DataManager | 数据管理,保存/加载游戏数据 |
Unity 实现
public class GameManager : MonoBehaviour{ public static GameManager Instance { get; private set; }
private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); }}注意事项
- 避免滥用单例,导致耦合度过高
- 考虑使用 ScriptableObject 替代部分单例
- 线程安全问题在 Unity 中较少出现,但需注意
2. 观察者模式(Observer)
概念
定义对象间的一种一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| 事件系统 | 玩家受伤通知、得分变化、任务完成 |
| UI 更新 | 血量变化时自动更新血条 |
| 成就系统 | 达成条件时触发成就奖励 |
实现方式
// 事件参数public class PlayerHealthChangedEvent{ public int CurrentHealth; public int MaxHealth;}
// 事件管理器public class EventManager{ public static EventManager Instance { get; private set; }
private Dictionary<string, List<System.Action<object>>> _listeners = new();
public void Subscribe(string eventName, System.Action<object> callback) { if (!_listeners.ContainsKey(eventName)) _listeners[eventName] = new List<System.Action<object>>(); _listeners[eventName].Add(callback); }
public void Publish(string eventName, object data = null) { if (_listeners.ContainsKey(eventName)) { foreach (var callback in _listeners[eventName]) { callback?.Invoke(data); } } }}
// 使用public class HealthBar : MonoBehaviour{ private void Start() { EventManager.Instance.Subscribe("PlayerHealthChanged", OnHealthChanged); }
private void OnHealthChanged(object data) { if (data is PlayerHealthChangedEvent e) { UpdateHealthBar(e.CurrentHealth, e.MaxHealth); } }}3. 状态机模式(State Machine)
概念
允许对象在内部状态改变时改变其行为,看起来好像修改了它的类。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| 角色状态 | 待机、行走、跑步、跳跃、攻击 |
| AI 行为 | 巡逻、追击、攻击、逃跑 |
| 游戏流程 | 开始菜单、游戏中、暂停、游戏结束 |
简单实现
public interface IState{ void Enter(); void Update(); void Exit();}
public class StateMachine{ private IState _currentState;
public void TransitionTo(IState newState) { _currentState?.Exit(); _currentState = newState; _currentState.Enter(); }
public void Update() { _currentState?.Update(); }}Unity 角色状态机示例
// 待机状态public class IdleState : IState{ private PlayerController _player;
public IdleState(PlayerController player) { _player = player; }
public void Enter() { _player.Animator.SetBool("IsWalking", false); }
public void Update() { float h = Input.GetAxisRaw("Horizontal"); if (Mathf.Abs(h) > 0.1f) { _player.StateMachine.TransitionTo(new WalkState(_player)); } }
public void Exit() { }}
// 行走状态public class WalkState : IState{ private PlayerController _player;
public WalkState(PlayerController player) { _player = player; }
public void Enter() { _player.Animator.SetBool("IsWalking", true); }
public void Update() { float h = Input.GetAxisRaw("Horizontal"); _player.transform.Translate(Vector3.right * h * _player.Speed * Time.deltaTime);
if (Mathf.Abs(h) < 0.1f) { _player.StateMachine.TransitionTo(new IdleState(_player)); } }
public void Exit() { }}4. 对象池模式(Object Pool)
概念
避免频繁的对象创建和销毁,复用已创建的对象。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| 子弹/炮弹 | 射击游戏中的大量子弹 |
| 粒子特效 | 爆炸、火花等频繁创建的特效 |
| 敌人 | 波次生成的敌人 |
| UI 元素 | 伤害数字、道具图标 |
实现
public class ObjectPool<T> where T : class, new(){ private Stack<T> _pool = new(); private System.Func<T> _createFunc;
public ObjectPool(System.Func<T> createFunc) { _createFunc = createFunc; }
public T Get() { return _pool.Count > 0 ? _pool.Pop() : _createFunc(); }
public void Return(T obj) { _pool.Push(obj); }}
// Unity 中的对象池public class BulletPool : MonoBehaviour{ public GameObject bulletPrefab; private ObjectPool<GameObject> _pool;
private void Start() { _pool = new ObjectPool<GameObject>(() => { return Instantiate(bulletPrefab); }); }
public GameObject GetBullet() { var bullet = _pool.Get(); bullet.SetActive(true); return bullet; }
public void ReturnBullet(GameObject bullet) { bullet.SetActive(false); _pool.Return(bullet); }}注意事项
- 设置合理的池子容量上限
- 对象回收时注意重置状态
- 考虑线程安全问题
5. 命令模式(Command)
概念
将请求封装成对象,从而允许参数化和排队执行请求。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| 输入处理 | 键盘按键映射为具体命令 |
| 撤销/重做 | 记录操作历史,支持撤销重做 |
| AI 命令 | 给 AI 单位下达移动、攻击等命令 |
| 回放系统 | 录制操作命令并回放 |
实现
// 命令接口public interface ICommand{ void Execute(); void Undo();}
// 移动命令public class MoveCommand : ICommand{ private Transform _target; private Vector3 _direction; private Vector3 _previousPosition;
public MoveCommand(Transform target, Vector3 direction) { _target = target; _direction = direction; }
public void Execute() { _previousPosition = _target.position; _target.position += _direction; }
public void Undo() { _target.position = _previousPosition; }}
// 命令管理器public class CommandManager{ private Stack<ICommand> _history = new(); private Stack<ICommand> _redoStack = new();
public void ExecuteCommand(ICommand command) { command.Execute(); _history.Push(command); _redoStack.Clear(); }
public void Undo() { if (_history.Count > 0) { var cmd = _history.Pop(); cmd.Undo(); _redoStack.Push(cmd); } }
public void Redo() { if (_redoStack.Count > 0) { var cmd = _redoStack.Pop(); cmd.Execute(); _history.Push(cmd); } }}6. 工厂模式(Factory)
概念
定义创建对象的接口,让子类决定实例化哪个类。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| 敌人生成 | 根据波次生成不同类型敌人 |
| 道具生成 | 随机掉落不同道具 |
| 技能释放 | 创建不同的技能实例 |
| UI 生成 | 动态创建不同类型的界面 |
实现
// 抽象工厂public abstract class EnemyFactory{ public abstract Enemy CreateEnemy(EnemyType type);}
// 具体工厂public class UnityEnemyFactory : EnemyFactory{ public override Enemy CreateEnemy(EnemyType type) { Enemy enemy = type switch { EnemyType.Slime => Resources.Load<Slime>("Prefabs/Enemies/Slime"), EnemyType.Goblin => Resources.Load<Goblin>("Prefabs/Enemies/Goblin"), EnemyType.Dragon => Resources.Load<Dragon>("Prefabs/Enemies/Dragon"), _ => throw new ArgumentException("Unknown enemy type") };
return Instantiate(enemy); }}
// 使用public class WaveManager : MonoBehaviour{ private EnemyFactory _factory = new UnityEnemyFactory();
public void SpawnWave(WaveConfig config) { foreach (var enemyType in config.Enemies) { var enemy = _factory.CreateEnemy(enemyType); enemy.transform.position = GetSpawnPoint(); } }}7. 外观模式(Facade)
概念
为复杂的子系统提供一个统一的高层接口,简化子系统使用。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| 音频系统 | 统一管理背景乐、音效、语音 |
| 存档系统 | 统一管理存档、读档、自动存档 |
| 战斗系统 | 整合伤害计算、Buff 管理、战斗结算 |
实现
// 子系统public class AudioSubsystem { }public class SaveSubsystem { }public class NetworkSubsystem { }
// 外观类public class GameFacade{ public AudioSubsystem Audio { get; } public SaveSubsystem Save { get; } public NetworkSubsystem Network { get; }
public GameFacade() { Audio = new AudioSubsystem(); Save = new SaveSubsystem(); Network = new NetworkSubsystem(); }
public void Initialize() { Audio.Init(); Save.Init(); Network.Connect(); }}
// 使用方不需要了解子系统细节public class GameManager : MonoBehaviour{ private GameFacade _facade;
private void Start() { _facade = new GameFacade(); _facade.Initialize(); }}8. 策略模式(Strategy)
概念
定义一系列算法,把它们一个个封装起来,使它们可以相互替换。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| 移动方式 | 走路、跑步、蹲行、翻滚 |
| 攻击方式 | 近战、远程、法术 |
| AI 寻路 | A*、Dijkstra、导航网格 |
| 难度设置 | 简单、普通、困难 |
实现
// 策略接口public interface IMoveStrategy{ void Move(Transform transform, float speed);}
// 行走策略public class WalkStrategy : IMoveStrategy{ public void Move(Transform transform, float speed) { float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); Vector3 dir = new Vector3(h, 0, v).normalized; transform.position += dir * speed * Time.deltaTime; }}
// 翻滚策略public class RollStrategy : IMoveStrategy{ public void Move(Transform transform, float speed) { if (Input.GetKeyDown(KeyCode.Space)) { // 执行翻滚 } }}
// 使用public class PlayerController : MonoBehaviour{ public IMoveStrategy MoveStrategy { get; set; }
private void Update() { MoveStrategy?.Move(transform, Speed); }}9. 装饰器模式(Decorator)
概念
动态地给对象添加额外的职责,比继承更灵活。
游戏开发中的应用
| 场景 | 说明 |
|---|---|
| Buff 系统 | 给角色添加各种增益/减益效果 |
| 装备强化 | 武器附加元素伤害、属性强化 |
| 技能强化 | 基础技能加强化效果 |
实现
// 基础攻击public class AttackComponent{ public virtual int CalculateDamage() { return 10; }}
// 装饰器基类public abstract class AttackDecorator : AttackComponent{ protected AttackComponent _baseAttack;
public AttackDecorator(AttackComponent baseAttack) { _baseAttack = baseAttack; }
public override int CalculateDamage() { return _baseAttack.CalculateDamage(); }}
// 火焰附魔public class FireEnchantment : AttackDecorator{ public FireEnchantment(AttackComponent baseAttack) : base(baseAttack) { }
public override int CalculateDamage() { int baseDamage = base.CalculateDamage(); int fireDamage = 5; Debug.Log($"造成 {baseDamage} 物理伤害 + {fireDamage} 火焰伤害"); return baseDamage + fireDamage; }}
// 冰霜附魔public class IceEnchantment : AttackDecorator{ public IceEnchantment(AttackComponent baseAttack) : base(baseAttack) { }
public override int CalculateDamage() { int baseDamage = base.CalculateDamage(); int iceDamage = 3; Debug.Log($"造成 {baseDamage} 物理伤害 + {iceDamage} 冰霜伤害 + 减速效果"); return baseDamage + iceDamage; }}10. MVC 与 MVVM 架构
MVC(Model-View-Controller)
Model(模型) ←→ View(视图) ↑ ↑ └──── Controller ────┘| 部分 | 职责 | 游戏开发应用 |
|---|---|---|
| Model | 数据和业务逻辑 | 角色数据、道具数据 |
| View | UI 显示 | 血条、伤害数字 |
| Controller | 处理输入,协调 Model 和 View | 输入控制、UI 事件响应 |
MVVM(Model-View-ViewModel)
适用于复杂 UI 系统:
- Model:数据
- View:界面(不直接操作数据)
- ViewModel:界面逻辑,数据绑定
// ViewModel 示例public class HealthBarViewModel : MonoBehaviour{ public Observable<int> CurrentHealth { get; } = new(); public Observable<int> MaxHealth { get; } = new();
private void Start() { // 绑定到 View CurrentHealth.OnChanged += UpdateHealthBar; }
public void TakeDamage(int damage) { CurrentHealth.Value = Mathf.Max(0, CurrentHealth.Value - damage); }
private void UpdateHealthBar(int health) { healthBarImage.fillAmount = (float)health / MaxHealth.Value; }}设计模式选用指南
按场景选择
| 场景 | 推荐模式 |
|---|---|
| 全局唯一对象 | 单例模式 |
| 事件通知系统 | 观察者模式 |
| 角色/AI 状态 | 状态机模式 |
| 频繁创建销毁的对象 | 对象池模式 |
| 输入处理/撤销重做 | 命令模式 |
| 对象创建 | 工厂模式 |
| 复杂系统整合 | 外观模式 |
| 算法替换 | 策略模式 |
| Buff/装备强化 | 装饰器模式 |
| UI 系统 | MVC/MVVM |
避免过度设计
- 不要为了用模式而用模式
- 简单问题简单解决
- 代码可读性优先
- 后续维护成本考虑
总结
设计模式是工具,不是目的。掌握核心模式,理解其适用场景:
| 模式 | 核心价值 |
|---|---|
| 单例 | 全局访问点 |
| 观察者 | 解耦事件通知 |
| 状态机 | 清晰的状态管理 |
| 对象池 | 性能优化 |
| 命令 | 封装请求/撤销 |
| 工厂 | 封装创建逻辑 |
| 外观 | 简化复杂系统 |
| 策略 | 算法可替换 |
| 装饰器 | 动态扩展功能 |
实践建议:从简单模式开始,在实际项目中体会模式的威力。遇到问题时思考”这个问题是否有成熟的解决方案”,而非强行套用模式。
参考资源
- 《设计模式:可复用面向对象软件的基础》
- 《游戏编程模式》- Robert Nystrom
- Unity 官方设计模式教程
本文结合游戏开发实战经验,系统整理了常用设计模式及其 Unity 实现方式。
游戏开发常用设计模式完全指南
https://gzhblog.cn/posts/2026-03/游戏开发常用设计模式完全指南/ 写作概览
20 篇
文章
2.9万
总字数
2.5h
阅读时长
1,464
均字数
年度发文
2026 20
Unreal相关
Unity相关
写作概览
20 篇
文章
2.9万
总字数
2.5h
阅读时长
1,464
均字数
年度发文
2026 20
Unreal相关
Unity相关