首页/ 第 6 章 · 游戏对象与组件交互/ 第 86 课
LESSON 86 · 游戏对象与组件交互

单例模式 Singleton

单例模式已掌握。下一课复习命名与代码规范,写“干净”的代码。

⏱ 约 15 分钟📊 难度:入门🗂 第 6 章 · 游戏对象与组件交互📍 第 86 / 300 课
课程进度
86 / 300

🎯本节学习目标

  • 理解单例的概念
  • 掌握单例写法
  • 用单例管理全局逻辑

🚀课程导读

“任何脚本都能拿到 GameManager”“得分管理只有一个实例”——单例模式解决这两个需求,是游戏开发最常用的模式。

什么是单例

“全游戏只此一个,且谁都能访问”。

  1. 单例 = 一个类在整个游戏中只允许存在一个实例(Instance),并提供全局静态访问。
  2. 【为什么用】跨脚本通信频繁时,用单例代替 Find/拖引用,代码更简洁。
  3. 【典型】GameManager(游戏流程)、ScoreManager(分数)、AudioManager(音频)、UIManager(界面)。
  4. 【单例本质】一个 static 字段保存“唯一的自己”,通过 Instance 属性访问。
  5. 【注意】单例虽方便,滥用会耦合;架构上要克制(第 279 课设计模式)。
💡
单例 = static 字段 + 赋值 + 全局访问,三行核心。

单例写法

标准模板。

  1. 新建脚本 GameManager(继承 MonoBehaviour):
  2. public class GameManager : MonoBehaviour {
  3. public static GameManager Instance;
  4. void Awake() { if (Instance == null) { Instance = this; } else { Destroy(gameObject); } }
  5. public int score;
  6. public void AddScore(int n) { score += n; }
  7. }
  8. 【说明】Awake 里把自己赋给 Instance;若已有实例则销毁重复的,保证唯一。
  9. 【跨场景保留】在 Awake 里加 DontDestroyOnLoad(gameObject); 让单例跨场景存活(第 238 课)。
  10. 【使用】任何脚本:GameManager.Instance.AddScore(10);
  11. 【进阶】泛型单例模板、属性封装(Instance 用属性 + get 自动查找)——进阶。
  12. 【实战】创建空对象挂 GameManager,在玩家脚本里调用 GameManager.Instance.AddScore(10),打印分数。
单例让“谁都能找到总管”,但也别把所有逻辑塞进一个巨大单例,注意职责拆分。

常见错误与排查

错误:Instance 为 null?
原因:单例未挂载到场景或未初始化
解决:确认对象上挂了单例脚本;在 Awake/Start 之后使用;跨场景需 DontDestroyOnLoad。

动手练习

课后小任务(做出来才算真的学会)

  • 实现一个 ScoreManager 单例
  • 在两个不同脚本里访问同一个单例
  • 用 DontDestroyOnLoad 让单例跨场景保留

本节小结

单例模式已掌握。下一课复习命名与代码规范,写“干净”的代码。

完成打卡后,主站会实时更新你的学习进度 🎯

← 上一课ScriptableObject 数据对象