HOME / 第 6 部分 · 数据与进阶开发 / 第 67 课
MODULE 6 · 数据与进阶开发

第 67 课 · 单例(Autoload)

⏱ 预计时长 30 分钟📊 难度 进阶📚 模块 第 6 部分 · 数据与进阶开发

🎯 本课学习目标

单例(Autoload)是全局共享的节点,任何场景都能访问——全局数据的最佳归宿。

📖 详细教学步骤

什么是 Autoload?概念

Autoload(自动加载)是启动时就创建的全局节点:

  • 一直存在,跨场景不销毁
  • 任何脚本都能直接访问(如 Globals.xxx)
  • 适合:全局数据(金币/设置)、全局服务(音乐/存档/场景管理)

创建单例脚本搭建

  1. 资源面板新建脚本 globals.gd
  2. 写全局数据与函数
  3. 项目设置 → 全局 → Autoload 列表 → 添加
GDSCRIPTextends Node

# 全局数据
var score: int = 0
var player_hp: int = 100
var current_level: int = 1
var settings: Dictionary = {}

# 全局功能
func add_score(points: int):
    score += points
    print("总分:", score)

func reset_run():
    score = 0
    player_hp = 100
    current_level = 1

注册 Autoload操作

  1. 菜单 项目 → 项目设置
  2. 左侧选 全局(Globals)→ Autoload
  3. Path 选择 globals.gd,点「添加」
  4. 列表中显示 Globals(名字默认取脚本名)

💡 注册后,游戏启动自动创建该节点,名字即脚本名。

访问单例代码

任何脚本直接按名字访问:

GDSCRIPT# 任意场景的脚本
func _ready():
    Globals.add_score(50)
    print(Globals.score)
    Globals.settings["volume"] = 0.9

# 注意:单例脚本里不要写 extends Node2D 等,用 extends Node

单例最佳实践规范

  • ✅ 全局数据(设置/进度/货币)
  • ✅ 全局服务(音频管理器、存档管理器、场景管理器)
  • ✅ 跨场景通信
  • ⚠️ 别滥用:游戏逻辑细节留在场景脚本
  • ⚠️ 别存节点引用(跨场景会失效)

单例间的通信进阶

单例可以互相访问,也可发信号给场景:

GDSCRIPT# GameManager.gd
signal game_over(score: int)

func end_game():
    game_over.emit(Globals.score)

# 场景里
func _ready():
    GameManager.game_over.connect(_on_game_over)

func _on_game_over(final_score: int):
    show_result(final_score)
⚠️
单例名冲突?

Autoload 名不能与内置类名冲突。若脚本叫 timer.gd 会与 Timer 冲突,改个名。

⚠️
单例里访问不到场景节点?

单例不在任何场景里,用 get_tree() 或 $ 都拿不到场景节点。需要交互就用信号。

🧪 动手试一试

🏋️ 课后练习

把滚球游戏的分数、金币、设置全部迁到 Globals 单例,主场景读取显示。

Globals.score 全局累加;切场景后仍保留。

💡

单例是「跨场景全局状态」的官方答案,比到处传参优雅。

💡

建议单例名大写开头(Globals、GameManager、AudioManager)。

🎓 本课小结

Autoload 单例 = 启动即创建的全局节点:注册于项目设置,任何场景直接访问;管全局数据与全局服务,跨场景通信用信号。