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

第 64 课 · 异步加载大场景与资源

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

🎯 本课学习目标

大场景加载时游戏卡死,体验极差。本课用异步加载解决,并做真实进度条。

📖 详细教学步骤

为什么要异步加载?概念

同步加载(change_scene_to_file)会阻塞主线程:

  • 大场景(很多贴图/模型)加载需要 1-5 秒
  • 期间画面冻结、声音卡顿
  • 异步加载 = 后台慢慢加载,画面照常运行

后台加载场景代码

ResourceLoader 线程加载:

GDSCRIPTextends Node

var loading_scene: String = "res://scenes/big_level.tscn"
var progress: Array = []

func start_load():
    # 发起后台加载请求
    ResourceLoader.load_threaded_request(loading_scene)

func _process(delta):
    # 查询加载状态
    var status = ResourceLoader.load_threaded_get_status(loading_scene, progress)
    if status == ResourceLoader.THREAD_LOAD_LOADED:
        # 加载完成,取回场景
        var scene = ResourceLoader.load_threaded_get(loading_scene)
        get_tree().change_scene_to_packed(scene)
    elif status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
        # 进行中,更新进度条
        if progress.size() > 0:
            $ProgressBar.value = progress[0] * 100
            $Label.text = "加载中 %d%%" % int(progress[0] * 100)

加载多个资源代码

需要多个资源一起加载:

GDSCRIPTfunc load_all():
    ResourceLoader.load_threaded_request("res://scenes/level.tscn")
    ResourceLoader.load_threaded_request("res://audio/bgm.ogg")
    ResourceLoader.load_threaded_request("res://textures/hero.png")

进度条 UI搭建

  1. 在加载场景(LoadScreen)加 ProgressBar + Label
  2. ProgressBar Min=0 Max=100
  3. 异步加载时按 progress[0] 更新
  4. 加载完自动切场景

💡 真实进度条比「转圈图标」更有专业感。

预加载常用资源进阶

主菜单时就把战斗场景加载好:

GDSCRIPTfunc _ready():
    # 提前加载
    ResourceLoader.load_threaded_request("res://scenes/battle.tscn")

func _process(delta):
    var st = ResourceLoader.load_threaded_get_status("res://scenes/battle.tscn")
    if st == ResourceLoader.THREAD_LOAD_LOADED:
        battle_ready = true   # 准备好,随时可进

注意事项注意

  • load_threaded_get 只能在状态为 LOADED 时调用,否则报错
  • 同一资源重复请求会返回同一个结果(缓存)
  • Web 平台(HTML5)异步加载有限制,注意兼容
⚠️
load_threaded_get 报错?

先判断状态 == THREAD_LOAD_LOADED 再 get。加载中 get 会报错。

⚠️
进度条到 90% 就不动了?

最后阶段在组装场景,进度接近满时直接等完成即可。

🧪 动手试一试

🏋️ 课后练习

做一个主菜单,点击「开始」→ 加载画面(带进度条)→ 异步加载大场景 → 自动进入。

load_threaded_request + _process 轮询 + 进度更新。

💡

异步加载适合:章节关卡、大地图、战斗场景。

💡

先加载到内存再用 change_scene_to_packed 切换,几乎零卡顿。

🎓 本课小结

异步加载:load_threaded_request 后台请求 → _process 轮询状态 → THREAD_LOAD_LOADED 取回切场景;配合进度条让加载过程专业流畅。