2556 字
13 分钟

游戏开发常用设计模式完全指南

系统讲解游戏开发中最常用的设计模式,包括单例模式、观察者模式、状态机模式、对象池模式、命令模式等,并结合Unity和游戏开发实战进行深入分析。

前言#

设计模式是解决特定问题的最佳实践,是经过大量项目验证的代码组织方式。在游戏开发中,合理运用设计模式能让代码更清晰、更易维护、更易扩展。本文系统讲解游戏开发中最常用的设计模式。


1. 单例模式(Singleton)#

概念#

确保一个类只有一个实例,并提供全局访问点。

游戏开发中的应用#

场景说明
GameManager游戏状态管理,全局唯一
AudioManager音频管理,统一控制背景音乐、音效
UIManagerUI 管理,协调所有界面
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数据和业务逻辑角色数据、道具数据
ViewUI 显示血条、伤害数字
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

避免过度设计#

  • 不要为了用模式而用模式
  • 简单问题简单解决
  • 代码可读性优先
  • 后续维护成本考虑

总结#

设计模式是工具,不是目的。掌握核心模式,理解其适用场景:

模式核心价值
单例全局访问点
观察者解耦事件通知
状态机清晰的状态管理
对象池性能优化
命令封装请求/撤销
工厂封装创建逻辑
外观简化复杂系统
策略算法可替换
装饰器动态扩展功能

实践建议:从简单模式开始,在实际项目中体会模式的威力。遇到问题时思考”这个问题是否有成熟的解决方案”,而非强行套用模式。


参考资源#


本文结合游戏开发实战经验,系统整理了常用设计模式及其 Unity 实现方式。

游戏开发常用设计模式完全指南
https://gzhblog.cn/posts/2026-03/游戏开发常用设计模式完全指南/
作者
384400
发布于
2026-03-02
许可协议
CC BY-NC-SA 4.0

这篇文章是否对你有帮助?