Read this manual in English

热重载资源

Defold 允许资源的热重载. 开发游戏时此功能可以大大节省时间. 它可以让你在游戏运行时修改代码和内容. 经常用于:

  • 使用 Lua 脚本调整游戏.
  • 编辑调整可视元素 (比如粒子特效或 GUI 元素) 即时观察效果.
  • 编辑调整 shader 代码即时观察效果.
  • 测试时重启关卡, 设定状态之类—而不用关闭游戏.

如何热重载

从编辑器启动游戏 (Project ▸ Build).

选择菜单项 File ▸ Hot Reload 或者通过键盘快捷键实现热重载:

Reloading resources

设备上的热重载

除了桌面设备, 热重载也可以其他设备上使用. 要在设备上使用热重载, 在移动设备上运行游戏的调试(debug)版本, 或者运行 开发应用 , 然后在编辑器中选择目标设备:

target device

当编译运行时, 编辑器会把所有资源上传到设备上运行着的游戏里. 也就是说, 热重载的所有文件都会在设备上进行更新.

比如, 想在手机上运行着的游戏 GUI 上添加几个按钮, 仅需要打开 GUI 文件:

reload gui

加入按钮, 保存并热重载 GUI 文件. 然后在手机上就能看见新建的按钮了:

reloaded gui

当你将某个文件进行热重载, 游戏引擎会在控制台列出每个被热重载了的资源文件.

重载脚本

任何被重载的 Lua 脚本文件都会在 Lua 运行环境里重新执行.

local my_value = 10

function update(self, dt)
    print(my_value)
end

修改 my_value 为 11 然后进行热重载就可以看到改动立刻生效了:

...
DEBUG:SCRIPT: 10
DEBUG:SCRIPT: 10
DEBUG:SCRIPT: 10
INFO:RESOURCE: /main/hunter.scriptc was successfully reloaded.
DEBUG:SCRIPT: 11
DEBUG:SCRIPT: 11
DEBUG:SCRIPT: 11
...

注意热重载不影响生命周期函数的执行. 比如热更新不会自动调用 init() 函数. 当然在这些函数上所做的修改, 还是会被更新的.

重载 Lua 模块

只要在模块文件中加入了全局变量, 重载此模块文件后变量也会随之更新:

--- my_module.lua
my_module = {}
my_module.val = 10
-- user.script
require "my_module"

function update(self, dt)
    print(my_module.val) -- hot reload "my_module.lua" and the new value will print
end

Lua 模块的一个常用方法是构造一个局部数据表, 输出并返回它:

--- my_module.lua
local M = {} -- a new table object is created here
M.val = 10
return M
-- user.script
local mm = require "my_module"

function update(self, dt)
    print(mm.val) -- will print 10 even if you change and hot reload "my_module.lua"
end

更改并重载 “my_module.lua” 并 不会 更新 “user.script” 的输出值. 关于这种情况的成因以及如何避免, 详见 模块教程.

on_reload() 函数

所有脚本组件都能定义 on_reload() 函数. 如果此函数存在, 则在重载时会自动被调用. 对于检查和修改数据, 发送消息之类的很有用:

function on_reload(self)
    print(self.velocity)

    msg.post("/level#controller", "setup")
end

重载shader数据

当重载顶点与片元着色器时, GLSL 代码会被显卡驱动程序重新编译并上传至 GPU. 因为 GLSL 很底层的所以很有可能出现着色器代码崩溃的情况, 这种情况下游戏引擎也会崩溃.