Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
创建应用程序
Godot 拥有强大的内置 UI(用户界面)系统,而且它的体积非常小巧,这让它成为 Electron 或 Qt 等框架的理想替代品。
本页面提供了使用 Godot 开发非游戏类应用的指南,以及执行常见任务以优化桌面集成的操作说明。
备注
Godot 首先且本质上是一个游戏引擎。这意味着,用 Godot 来开发普通应用只是其功能带来的一个‘副产品’,而并不是它开发团队的首要重心。
参见
请查看 Material Maker 和 Pixelorama,以了解用 Godot 制作的开源应用程序的例子。
执行常见任务
创建多窗口
此功能仅在 Windows、 macOS 和 Linux 系统上受支持(仅限 X11/XWayland,不支持原生 Wayland 模式)。
可以使用 Window 节点来创建额外的窗口。这些窗口能够独立于主应用程序窗口进行移动、调整大小、最小化和关闭。
不过,如果你关闭了主窗口,所有其他窗口也会随之关闭,因为关闭主窗口意味着整个程序进程会被结束。为了避免这种情况,你可以将主窗口最小化,并将其 无法获取焦点 属性设置为 true (这样它就会从任务栏和任务切换器中隐藏),然后在程序启动时立即创建额外的 Window 节点。在这种情况下,记得要为用户提供一种退出应用的替代方式,比如添加一个 托盘图标 。
限制窗口大小
大多数应用只有在达到某个最小窗口尺寸时,才能正常渲染(显示)内容。而对于更具体的使用场景,可能还需要强制限制一个最大窗口尺寸。
可以通过 Window 节点上的 min_size 和 max_size 属性来强制限制窗口大小。不过要记得,这些尺寸限制需要根据应用程序的缩放比例进行相应的倍增(具体细节请参阅关于 针对高 DPI 显示屏进行缩放 )。
小技巧
提醒一下,你可以在任意 Node(节点)上使用 get_window() 方法来获取根 Window 节点,从而对它进行属性设置。
使用原生文件对话框
此功能仅支持 Windows、 macOS 、Linux 和 Android 系统。
默认情况下,Godot 会使用它自己实现的 FileDialog 作为文件对话框。不过,你也可以选择改用操作系统原生的文件对话框。一般来说,用户会更喜欢后者,因为原生文件对话框能更好地融入桌面环境,带来更熟悉的操作体验。
你可以通过启用 FileDialog 节点上的 use_native_dialog 属性,来切换使用原生的文件对话框。需要注意的是,你必须在项目中使用到的每一个 FileDialog 节点上单独进行设置,因为目前并没有一个全局的项目设置可以统一控制这个行为。
macOS 上标准 FileDialog(左)与原生文件对话框(右)的对比
备注
关于(各)平台的支持情况,请参见 property description 了解详细信息。
另外,在 macOS 上,如果编辑器中启用了游戏内嵌(game embedding)功能,将不支持调用系统原生的文件对话框。如果你想在运行项目时测试这个功能,请务必先关闭游戏内嵌。具体操作是:切换到顶部的 面板,点击顶部工具栏最右侧的图标,然后取消勾选 。
在系统托盘中创建图标
此功能仅支持 Windows 和 macOS 系统。
你可以通过 StatusIndicator 节点,在系统托盘(也就是大家常说的通知区域)里创建一个或多个图标。除了可以设置鼠标悬停时显示的提示文本(tooltip)外,这个节点还能绑定一个 PopupMenu 节点,这样当你点击托盘图标时,就会弹出一个下拉菜单供你操作。
StatusIndicator 还有一个 pressed 信号,当用户点击这个图标时,该信号就会被触发。你可以利用它来执行某些操作,而不会弹出下拉菜单;或者根据用户按下的是鼠标的哪个按键(比如左键或右键),来执行不同的动作。
在创建了托盘图标之后,你可能还想实现 "点击关闭时最小化"(minimize on close)的行为。这意味着当用户尝试通过窗口管理器的 X 按钮关闭应用程序时,程序不会真正退出,而是会最小化隐藏到系统托盘里。要实现这个功能,请将以下脚本附加到一个 Autoload (自动加载)的 场景 上,并且该场景的根节点必须是一个 StatusIndicator。
extends StatusIndicator
# Disable this behavior when running from the editor with game embedding,
# as it doesn't cooperate well.
var tray_icon_supported = (
DisplayServer.has_feature(DisplayServer.FEATURE_STATUS_INDICATOR)
and not Engine.is_embedded_in_editor()
)
func _ready():
visible = false
if tray_icon_supported:
get_tree().auto_accept_quit = false
get_window().focus_entered.connect(
func():
# Hide the tray icon when the window gains focus,
# which means it was restored from its minimized state.
visible = false
)
pressed.connect(
func(_mouse_button, _position):
# Restore the application when the tray icon is clicked.
get_window().mode = Window.MODE_WINDOWED
)
func _notification(what):
if not tray_icon_supported:
return
match what:
NOTIFICATION_WM_CLOSE_REQUEST:
get_window().mode = Window.MODE_MINIMIZED
# Show the tray icon.
visible = true
关于如何覆盖用户尝试关闭应用程序时的默认行为,详情请参见 处理退出请求 (处理退出请求)。这一点非常重要,尤其是当用户有未保存的修改时,妥善处理可以避免数据丢失。
备注
当存在多个 StatusIndicator 节点时,它们在系统托盘中的排列顺序,取决于它们被添加到场景树中的先后顺序。
使用客户端窗口装饰
此功能仅支持 macOS 。
许多现代应用程序都采用 客户端装饰(CSD) ,而不再依赖操作系统的窗口管理器来绘制标题栏和窗口边框(即传统的服务器端装饰)。这样做不仅能让应用的外观更加个性化、可定制,还能让窗口与应用程序自身的 UI 界面实现更完美的融合。
目前,Godot 仅在 macOS 系统上支持客户端装饰(CSD)。你可以通过开启项目设置中的 display/window/size/extend_to_title (将窗口延伸至标题栏)选项来启用该功能。
macOS 上标准窗口装饰(上)与客户端装饰(下)的对比
启用客户端装饰后,原本的窗口边框将不再显示,而最小化、最大化和关闭按钮则会以悬浮叠加层的形式出现在应用程序的上方。你需要确保应用程序在顶部留出足够的边距(margin),以便让这些按钮能舒适地显示出来,同时还需要使用一个 Label 节点(或类似的控件)来手动显示窗口标题。
若要根据是否启用了客户端装饰来动态调整你的 UI,请使用 DisplayServer.has_feature 方法,并同时检查 Window.extend_to_title 的当前值(这也是项目设置所修改的内容):
func _ready():
if DisplayServer.has_feature(FEATURE_EXTEND_TO_TITLE) and get_window().extend_to_title:
# Adjust UI for client-side decorations (a MarginContainer node
# can be useful here). Also set the window title to be displayed
# according to the native window title.
$WindowTitle.visible = true
$WindowTitle.text = get_window().title
if OS.is_debug_build():
$WindowTitle.text += " (DEBUG)"
为了正确定位窗口标题,建议考虑使用 DisplayServer.window_get_safe_title_margins() ,它会返回一个 Vector3,其中 x 代表左边距, y 代表右边距(当系统使用从右向左的排版时会增加),而 z 代表高度。此外,你可以调用 DisplayServer.window_set_window_buttons_offset() 来调整关闭/最小化/最大化按钮的位置(通常是为了让它们垂直居中)。
macOS 上使用客户端装饰时的安全标题边距
备注
在 macOS 上,如果编辑器中启用了游戏内嵌(game embedding)功能,将不支持客户端装饰(client-side decorations)。如果你想在运行项目时测试这个功能,请务必先关闭游戏内嵌。具体操作是:切换到顶部的 面板,点击顶部工具栏最右侧的图标,然后取消勾选 。
在任务栏或 Dock 栏上显示进度状态
此功能仅支持 Windows 和 macOS 系统。
应用程序可以向操作系统汇报进度状态,这个状态会直接显示在任务栏或 Dock 栏的图标上。这个状态主要由两部分组成:当前的状态(比如进行中、已暂停、出错)以及完成的百分比。这样,即使用户当前没有聚焦在这个应用上(比如正在看别的窗口),也能直观地看到任务的进展啦。
在 macOS 的 Dock 栏上显示进度
这通常是通过将 ProgressBar 节点的进度,与汇报给操作系统的进度保持同步来实现的。
func set_progress(value, indeterminate = false):
$ProgressBar.value = value
$ProgressBar.indeterminate = indeterminate
if $ProgressBar.indeterminate:
get_window().set_taskbar_progress_state(DisplayServer.PROGRESS_STATE_INDETERMINATE)
else:
get_window().set_taskbar_progress_state(DisplayServer.PROGRESS_STATE_NORMAL)
# The taskbar progress value must be between `0.0` and `1.0`
# (values outside this range are clamped).
# However, ProgressBar can have minimum/maximum values that differ.
# We use the `remap()` method to convert the value to the range
# expected by taskbar progress reporting.
get_window().set_taskbar_progress_value(remap($ProgressBar.value, $ProgressBar.min_value, $ProgressBar.max_value, 0.0, 1.0))
有几种进度状态可供选择:无进度(会直接隐藏进度条)、不确定、正常、已暂停、出错。具体的细节可以查看类参考文档哦。
你还可以使用 Window.request_attention() 来让窗口在任务栏上闪烁(或者在 macOS 的 Dock 栏上跳动)。举个例子,当某个耗时较长的操作完成后,就可以用这个功能来吸引用户的注意。
备注
当编辑器中启用了游戏内嵌(game embedding)功能时,将不支持进度报告。如果你想在运行项目时测试这个功能,请务必先关闭游戏内嵌。具体操作是:切换到顶部的 面板,点击顶部工具栏最右侧的图标,然后取消勾选 。
发送桌面通知
Godot 目前不支持发送桌面通知的原生功能。
不过,在 macOS 和 Linux 上,你可以分别使用 osascript 和 notify-send 命令行工具来发送桌面通知:
func send_notification(title, message):
var app_name = ProjectSettings.get_setting("application/config/name")
if app_name.is_empty():
app_name = "Unnamed Project"
if OS.has_feature("macos") and not OS.is_sandboxed():
# Note that this will not work if the project is exported in sandbox mode
# (e.g. for the Mac App Store).
OS.execute("osascript", [
"-e",
'display notification \\"%s\\" with title \\"%s\\" subtitle \\"%s\\"' % [
message,
app_name,
title,
]
])
elif OS.has_feature("linuxbsd"):
OS.execute("notify-send", ["--app-name", app_name, title, message])
func _ready():
send_notification("Success", "Operation completed successfully.")
遗憾的是,Windows 上没有开箱即用的等效工具。
跨会话记住窗口位置和大小
Godot 没有内置的跨会话记忆窗口位置和大小功能,但可以通过脚本手动实现。一个支持多显示器设置的基础示例是使用包含此脚本的 Autoload :
extends Node
# Use a dedicated configuration file for the window state.
# This way, the application's other configuration files are left
# untouched and can be put in version control without unnecessary diffs
# being produced.
const CONFIG_WINDOW_PATH = "user://window.ini"
var config_file = ConfigFile.new()
func _enter_tree():
config_file.load(CONFIG_WINDOW_PATH)
# Do not restore previous window state if running from the editor
# with game embedding enabled.
if not Engine.is_embedded_in_editor():
var window_screen = config_file.get_value("main", "screen", -1)
if window_screen is int:
get_window().current_screen = window_screen
var window_mode = config_file.get_value("main", "mode", -1)
if window_mode is Window.Mode:
get_window().mode = window_mode
var window_position = config_file.get_value("main", "position", -1)
if window_position is Vector2i:
get_window().position = window_position
var window_size = config_file.get_value("main", "size", -1)
if window_size is Vector2i:
get_window().size = window_size
func _exit_tree():
# Save the current window state when the application is quit normally.
# In a real world scenario, it's recommended to also save this information
# regularly (e.g. with a Timer node), so that the window state can be
# restored after a crash or when terminated externally.
config_file.set_value("main", "screen", get_window().current_screen)
config_file.set_value("main", "mode", get_window().mode)
config_file.set_value("main", "position", get_window().position)
config_file.set_value("main", "size", get_window().size)
config_file.save(CONFIG_WINDOW_PATH)
备注
上面的示例仅追踪主窗口的位置。在生成多个窗口的应用程序中,你需要分别保存和加载每个窗口的位置和大小。
在启动画面(Splash Screen)期间隐藏窗口
对于某些应用程序,可能更倾向于隐藏默认启动画面,转而绘制一个带有进度条的自定义启动画面(或者,如果应用程序启动很快,甚至完全可以不要启动画面)。
Godot 缺乏在启动画面期间隐藏窗口的原生支持,但你可以通过在项目设置中使用一个非常小的透明窗口来实现这一点,然后在主场景加载完成后调整窗口大小并禁用透明度。
为此,项目设置应按照如下方式进行配置:
将 application/boot_splash/bg_color 设置为透明黑色(RGBA: 0, 0, 0, 0)。
这个脚本可以作为一个 Autoload (自动加载单例)来使用,以便在启动画面显示完毕后,恢复原始的(项目)设置:
extends Node
func _enter_tree():
# Wait a frame to be rendered before restoring the window properties.
# Otherwise, properties will be restored too early and the window border
# will show up around a transparent window.
await get_tree().process_frame
get_viewport().transparent_bg = false
get_window().transparent = false
get_window().borderless = false
get_window().size = Vector2i(1152, 648)
将应用程序显示为覆盖层
可以将应用程序窗口显示为悬浮在其他窗口之上的覆盖层。这对于小部件或系统监视器之类的应用非常有用。
要做到这一点,请启用以下 所有 项目设置:
-
这可以防止覆盖层(Overlay)接收键盘输入,同时也使其从任务栏和任务切换器中隐藏。覆盖层仍然可以接收鼠标输入(见下文)。
记得使用脚本来设置窗口的位置和大小,因为无边框窗口通常无法由用户直接拖动。
若要允许鼠标输入穿透到背景应用程序,请在作为覆盖层绘制的 Window 上将 mouse_passthrough (鼠标穿透)属性设置为 true 。你也可以在 mouse_passthrough_polygon (鼠标穿透多边形)中定义一个多边形,以便覆盖层上的某些区域仍然可以拦截鼠标输入。
此外,你可能还想将 exclude_from_capture (从捕获中排除)属性设置为 true ,以防止叠加层出现在截图或录屏中。此提示仅在 Windows 和 macOS 上实现,且属于“尽力而为”(best-effort)的机制,因此不应将其用作绝对的安全措施或数字版权管理(DRM)手段。
备注
当编辑器中启用了游戏内嵌(game embedding)功能时,将不支持以覆盖层(overlay)的形式显示。如果你想在运行项目时测试这个功能,请务必先关闭游戏内嵌。具体操作是:切换到顶部的 面板,点击顶部工具栏最右侧的图标,然后取消勾选 。
此外,请记住,如果目标应用程序使用了独占全屏模式,叠加层将无法显示在其上方。必须改用无边框全屏模式,叠加层才能可见。
此外,在 Windows 上使用混合 GPU 设置(例如 NVIDIA Optimus)时,透明窗口显示也存在一些 known issues 。切换渲染器可能有助于解决此问题。
在 Linux (X11) 系统上,如果用户在窗口管理器设置中禁用了合成器,那么透明效果将无法显示。
针对高 DPI 显示屏进行缩放
现代显示屏的像素密度差异很大,这通常意味着需要采用不同的缩放比例,以确保用户界面元素清晰可读。此外,也可以将此缩放比例作为手动调节选项提供给用户,以便他们能根据个人习惯调整,从而保持舒适的使用体验。
Godot 的多分辨率支持功能在配置得当的情况下,非常适合用于应用程序的缩放适配。请按照 non-game application section of the Multiple resolutions documentation 中的说明进行操作。
备注
Godot 目前仅在 macOS、Android 和 Linux(仅限 Wayland 协议)系统上支持从操作系统设置中读取屏幕缩放比例。在 Linux(X11 协议)和 Windows 系统上,你需要提供一个手动缩放选项,以便用户根据需要调整用户界面的缩放比例。
屏幕阅读器集成
屏幕阅读器通过朗读用户界面元素并提供导航控制,使视障人士能够使用应用程序。盲文显示器则是另一种方法,它们同样依赖辅助功能信息来正常工作。
Godot 会自动检测是否有屏幕阅读器在运行,如果检测到,就会自动启用辅助功能支持。你可以在 项目设置 中通过 accessibility/general/accessibility_support 来配置此项:如果不需要,可以将其禁用。你也可以强制启用它,这在使用的辅助功能调试工具未被 Godot 识别为屏幕阅读器时非常有用。
Godot 使用 AccessKit 库来实现与屏幕阅读器的集成。
小技巧
由于屏幕阅读器支持是直接使用屏幕阅读器应用程序本身来播放音频(而不是通过 Godot 项目),因此即使如在下文中所述将音频驱动程序设置为 Dummy ,它也能正常工作。
强烈建议在你的目标平台上,使用主流的屏幕阅读器来测试你的应用程序,以确保视障用户也能获得良好的使用体验。常见的例子包括 Windows 上的 NVDA、macOS 上的`VoiceOver <https://www.apple.com/accessibility/features/?vision>`__ 以及 Linux 上的 Orca。
要让屏幕阅读器的支持达到良好的可用性水平,需要做大量的工作。你需要使用 Control.accessibility_name 和 Control.accessibility_description 属性来定义无障碍标签,并确保用户界面在被屏幕阅读器读取时,其流程符合逻辑顺序。
参见
另请参阅 文本转语音 ,了解独立于屏幕阅读器之外的文本转语音功能。
推荐的项目设置
桌面集成
为了让应用程序能更好地融入桌面环境,你可以按如下方式设置这些项目选项:
启用 application/config/use_custom_user_dir,并将 application/config/custom_user_dir_name 设置为适合你应用程序的名称。这样可以确保用户的设置和文件存储在一个专用的文件夹中,而不是 :ref:默认的 Godot 文件夹 default Godot folder。按照惯例,在 Windows 上使用普通大小写(例如
Application Name),而在 macOS 和 Linux 上使用短横线命名法(例如application-name)是个好主意。使用 application/config/windows_native_icon (ICO 格式)和 application/config/macos_native_icon (ICNS 格式)来配置符合操作系统设计指南的原生图标。默认情况下,Godot 会根据项目图标自动生成原生图标,但这并不总是最优的效果。
在 Windows 上,使用手动设计的 ICO 文件可以让你为不同的分辨率设置不同的图标。这可以用来在低分辨率下制作特殊的设计,以获得更好的可读性。
macOS 拥有与其他平台显著不同的 应用图标指南 <https://developer.apple.com/design/human-interface-guidelines/app-icons/>`__ 。使用专门定制的原生图标设计,能确保应用程序更好地融入其桌面环境。
禁用 display/window/subwindows/embed_subwindows ,这样额外的窗口就会使用操作系统的主题样式,并被系统视为原生的操作系统窗口。
性能
这里有一些项目设置,你可以用来降低 CPU、GPU 和内存的占用率:
如果你不需要 Forward+ 或 Mobile 渲染器独有的功能,请使用 Compatibility(兼容)渲染器。Compatibility 渲染器对硬件要求较低,通常启动速度也更快,这使得它成为应用程序的更好选择。使用此渲染器创建新窗口的速度也更快。
启用 application/run/low_processor_mode (低处理器模式),以降低 CPU 和 GPU 的占用率。开启后,项目只会在屏幕画面发生实际变化时,才会去渲染新的一帧。
请注意,在某些特定情况下,项目必须持续不断地进行重绘(例如,当界面上正在播放动画,或者显示了使用了
TIME变量的着色器时)。如果这种情况持续很长时间,将会导致明显的功耗增加,进而缩短电池续航时间,并增大风扇的噪音。为了排查项目持续重绘的具体原因,你可以先点击编辑器顶部的 ,然后再运行项目。此时,发生重绘的区域会在 1 秒钟内被红色高亮标记出来。你可以通过 debug/canvas_items/debug_redraw_time 和 debug/canvas_items/debug_redraw_color 这两个项目设置,来分别调整高亮标记的持续时间和显示颜色。应用程序能够绘制的最大帧率由 application/run/low_processor_mode_sleep_usec 决定。该值以每帧的微秒数表示,因此可以使用公式
1000000.0 / sleep_usec获得最大 FPS。默认情况下,此值设置为6900,对应大约 145 FPS 的最大值。你可以增加此值以进一步降低 CPU 和 GPU 的使用率,但代价是体验会变得不那么流畅。
禁用 display/window/energy_saving/keep_screen_on,这样当应用程序处于空闲状态时,屏幕可以根据操作系统的电源设置自动关闭。这种行为在游戏中通常是不需要的(例如在观看过场动画时),但在应用程序中,我们希望当用户没有积极使用软件时,屏幕能够自动关闭以节省电量。
如果你的应用程序不需要音频输出或输入,请将 audio/driver/driver 设置为
Dummy(注意区分大小写) 。这将阻止音频服务器启动,从而节省一些 CPU 和内存资源。这还能防止应用程序出现在操作系统的音频混音器中的“正在播放音频的应用程序”列表里。在 macOS 上,这还能确保应用程序不会阻止设备进入睡眠状态。如果你的应用程序不需要物理模拟(包括物体拾取/点击检测),请将 physics/2d/physics_engine 和 physics/3d/physics_engine 设置为
Dummy。这将阻止物理服务器启动,从而节省 CPU 和内存资源。这还能让 engine compilation configuration editor 自动检测到该项目未使用物理功能。考虑将 display/window/vsync/vsync_mode 设置为 Disabled (禁用),以减少输入延迟。这对于对延迟敏感的项目(例如绘图应用)特别有帮助。但这可能会增加功耗并导致屏幕撕裂,因此建议为用户提供一个选项,以便根据需要切换垂直同步。
请查看 Material Maker 和 Pixelorama,以了解用 Godot 制作的开源应用程序的例子。
移动端
在为移动平台设计应用程序时,你可以启用一些设置来提升易用性:
Android:
启用 input_devices/pointing/android/enable_long_press_as_right_click,允许用户通过长按手势来执行鼠标右键操作。
启用 input_devices/pointing/android/enable_pan_and_scale_gestures ,允许用户通过触摸手势进行平移和缩放。这将模拟 InputEventPanGesture (平移手势)和 InputEventMagnifyGesture (缩放手势)事件,这些事件可以在你的项目代码中进行处理,通常是由笔记本电脑的触控板发出的。
在 Android 导出预设中,禁用 (屏幕 > 沉浸式模式),以便在应用处于活动状态时显示系统的状态栏(顶部电量、时间那一栏)和导航栏(底部的返回、主页键等)。此外,开启 (屏幕 > 边缘到边缘),可以让状态栏和导航图标变为半透明,并悬浮显示在应用程序的上方。如果你这样做了,请务必确保你的应用程序在界面布局时留出了足够的空间给状态栏和导航图标。你可以使用 DisplayServer.get_display_safe_area 和 DisplayServer.get_display_cutouts 来获取应用程序可以安全绘制的区域范围。
iOS:
禁用 display/window/ios/hide_home_indicator 以在应用程序上方显示主屏幕指示器。
禁用 display/window/ios/hide_status_bar 以在应用程序运行时保持状态栏可见。
禁用 display/window/ios/suppress_ui_gesture 以允许 UI 手势立即生效,无需执行两次。
添加单元测试
在一个应用程序中,拥有 单元测试 通常比在游戏中更具价值。这可用于以自动化方式捕获回归错误,在逻辑能够清晰分离的应用程序场景中,这往往更容易实现。
GDScript 本身并没有内置单元测试框架,但社区维护了一些用于单元测试的插件:
对于 C# 和 GDExtension(C++、Rust 等),你可以使用标准测试框架,例如 NUnit 或 doctest。
优化发布包的体积
由于非游戏应用程序通常避免使用引擎的大部分功能,例如音频或 3D 功能,你可以编译一个优化的导出模板以减小其文件大小。这也会改善启动时间,尤其是在 Web 平台上,因为可执行文件的大小与初始化速度直接相关。
文件大小的减小通常很显著(相对于项目的大小而言),因为与游戏相比,应用程序包含的大型资产更少。请参阅 为尺寸优化构建 以了解执行此操作的更多信息。
打包成一个单独的可执行文件
默认情况下,Godot 会生成一个包含项目数据的 PCK 文件,并把它放在可执行程序(.exe)的旁边。这就意味着,如果你只移动了可执行程序,而没有同时把 PCK 文件一起移走,程序就没法运行了。这对于那些越来越倾向于‘单文件分发’的应用程序来说,显然不太理想。
如果你想让应用完全独立,变成一个单文件的可执行程序,可以在导出预设选项中开启 Embed PCK (嵌入 PCK)。这样会把 PCK 资源数据直接打包塞进可执行程序(.exe)内部,以后你就可以随意移动这个程序,而不用担心它因为找不到文件而损坏。另外,这也让你可以直接在 ZIP 压缩包里运行程序,完全不需要先把它解压出来。
备注
PCK 嵌入功能会根据平台的不同,存在一定的体积限制。对于非常庞大的应用(比如好几个 GB 的大型游戏),可能无法在所有平台上使用这个功能。具体的细节,建议去查看对应目标平台的导出文档哦。
创建便携式应用
当一个应用程序无需安装就能直接运行,并且它的所有配置信息都完全独立、只保存在它被解压的那个文件夹里时,这个应用就被称为 便携版(Portable) 。这样一来,你就可以把应用程序的文件直接放在 U 盘或类似的移动设备里,带到不同的电脑上随时使用,完全不需要经历繁琐的安装过程。
Godot 编辑器自带的 self-contained mode 目前还无法直接在项目内部使用。不过,你依然可以通过以下方法,选择将你自己的配置文件保存到包含可执行程序的那个文件夹里:
var config_path = OS.get_executable_path().get_base_dir().path_join("config.ini")
# Then use `config_path` to save/load configuration files using ConfigFile or similar.
你可能希望把便携模式做成可选的,因为并不是所有玩家都希望这样。通常的做法是,检测可执行程序所在的文件夹里是否存在某个特定的文件(比如一个命名为 portable.txt 的文件),只有当这个文件存在时,才把配置文件保存到可执行程序所在的文件夹里。
警告
请记住,这个功能(便携模式)只有在应用程序被解压到一个‘可写入’的位置时才会生效。如果可执行程序是在一个‘只读’的位置运行的,比如在 Windows 上的 C:\Program Files 目录里,就会导致权限报错。
制作安装包
虽然游戏通常通过 Steam 等启动器安装或以 ZIP 格式下载,但应用程序通常以安装程序的形式分发,以便更好地与桌面集成。安装程序可以执行诸如向开始菜单或桌面添加快捷方式、设置文件关联等操作。安装程序也可以通过命令行自动运行,这使其更适合企业环境。
Godot 没有对为导出项目创建安装程序的内置支持。不过,你仍然可以使用第三方工具创建自己的安装程序。
以下是一些可以用来制作安装程序的工具(不完全列表):
Windows: Inno Setup, NSIS
如果你拥有代码签名证书,请记得 同时 为你的安装程序和项目可执行文件进行签名。具体操作是:先 sign the exported project executable ,然后创建包含该已签名可执行文件的安装程序,最后再手动对你刚刚创建好的这个安装程序进行签名。
macOS: create-dmg
Linux: Flatpak
有一个 Godot BaseApp <https://github.com/flathub/org.godotengine.Godot.BaseApp>,可以作为为 Godot 项目创建 Flatpak 软件包的基础。有关使用此 BaseApp 的 Flatpak 示例,请参阅 Pixelorama Flatpak <https://github.com/flathub/com.orama_interactive.Pixelorama>。
资源
这些页面涵盖了一些常在非游戏应用之中执行的任务:
ConfigFile (用于保存用户偏好)