Godot实现游戏中加载内容
简介
开发游戏中,经常需要在游戏发布后添加若干内容。类似的功能有:
- 游戏增量更新,不需要重新下载游戏,只需要下载更新pck文件并放在对应的文件目录下,就可以实现游戏更新。
- DLC,DLC又称为游戏的后续可下载内容,通常为发售后付费追加的内容。
- MOD,Mod又称为游戏模组,可以由第三方开发,并添加到游戏中,用于修改游戏中的内容。使游戏更有趣。
以上这些情况,通常为游戏已经分发,但又由于某些原因希望在已发布的版本上增添一些内容。这时就可以阅读本篇博客为游戏添加加载资源包的功能。
在游戏中添加加载器
我使用的逻辑是:
- 游戏一开始会加载一个加载中页面
- 在加载页面中,会检测某一个目录是否存在(可以为 /dlcs、/mods、/updates)
- 如果目录存在,则会循环判断目录中的每一个文件是否是以
pck
后缀结尾。 - 如果是则将该资源包加载到游戏中。否则跳过继续检查。
- 等待所有文件都检测后,进入游戏。
代码
gdscript
extends Control
@export_file('*.tscn') var start_scene
func _ready() -> void:
load_dlc()
func load_dlc() -> void:
var dlc_dir = DirAccess.open('./dlc')
if dlc_dir != null:
print(dlc_dir.get_current_dir())
dlc_dir.list_dir_begin()
var file_name = dlc_dir.get_next()
while file_name != "":
if dlc_dir.current_is_dir():
print("Found directory: " + file_name)
else:
print("Found file: " + file_name)
if file_name.ends_with("pck"):
var success = ProjectSettings.load_resource_pack('./dlc/' + file_name)
if success:
print("加载DLC {0} 成功", [file_name])
else:
printerr("加载DLC {0} 失败", [file_name])
file_name = dlc_dir.get_next()
else:
print("没有dlc目录")
# 重新加载页面
await get_tree().create_timer(0.1).timeout
get_tree().change_scene_to_file(start_scene)
示例项目
修改dlc文件夹名称,运行start_game查看结果。
如果成功加载DLC中的pck文件,则会在游戏场景中看到一个可以跳转场景的按钮。
QA
Q: 为什么要添加一个加载中页面?
A: 因为pck中的文件可能会修改开始游戏的场景,如果pck资源包中有替换开始页面的内容,则不会自动更新,需要调用代码get_tree().relaod_current_scene()
,但这时可能会出现报错,报错内容为ERROR: Parent node is busy adding/removing children, 'remove_child()' can't be called at this time.
。所以我使用的是添加一个加载中场景并在加载完成后再切换到开始页面。Q: 如何实现Mod的加载列表?
A: 通常游戏会在开始界面中添加一个页面,用来管理开启或关闭某些mod,此时可以在加载的时候生成一个配置文件,游戏首先读取配置文件获取到mod列表,然后再按照顺序去mods文件夹中加载开启的mod。