This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English

GUI 脚本

为了控制 GUI 逻辑和动画节点要使用 Lua 脚本. GUI 脚本和游戏对象脚本一样, 但是扩展名不一样而且使用的函数集不一样: 使用 gui 模块函数.

在 GUI 上添加脚本

要在 GUI 上添加脚本, 首先在 Assets 浏览器里右键点击 再在弹出菜单选择 New ▸ Gui Script 来创建 GUI 脚本.

编辑器会自动打开脚本文件. 它基于一个模板, 各种空白生命周期函数齐全, 跟游戏对象脚本一样:

function init(self)
   -- Add initialization code here
   -- Remove this function if not needed
end

function final(self)
   -- Add finalization code here
   -- Remove this function if not needed
end

function update(self, dt)
   -- Add update code here
   -- Remove this function if not needed
end

function on_message(self, message_id, message, sender)
   -- Add message-handling code here
   -- Remove this function if not needed
end

function on_input(self, action_id, action)
   -- Add input-handling code here
   -- Remove this function if not needed
end

function on_reload(self)
   -- Add input-handling code here
   -- Remove this function if not needed
end

要把脚本添加到 GUI 组件, 打开 GUI 蓝图文件, 在 Outline 里选择根节点显示出 GUI Properties. 把 Script 属性设置为脚本文件即可.

Script

如果这个 GUI 组件被添加到游戏中的游戏对象里, 它上面的脚本就可以运行了.

“gui” 命名空间

GUI 脚本访问 gui 命名空间及其 所有gui函数. go 命名空间不可用, 所以要注意区分游戏对象的脚本组件以及二者间的消息传递. 尝试使用 go 函数会报错:

function init(self)
   local id = go.get_id()
end
ERROR:SCRIPT: /main/my_gui.gui_script:2: You can only access go.* functions and values from a script instance (.script file)
stack traceback:
   [C]: in function 'get_id'
   /main/my_gui.gui_script:2: in function </main/my_gui.gui_script:1>

消息传递

游戏运行时 GUI 脚本可与其他对象互相传递消息, 同其他脚本组件相同.

定位 GUI 组件也与其他脚本组件中定位方法相同:

local stats = { score = 4711, stars = 3, health = 6 }
msg.post("hud#gui", "set_stats", stats)

message passing

定位节点

GUI 中的节点可由脚本控制. 在编辑器中每个节点都有唯一 Id:

message passing

Id 使得脚本引用节点并对其使用 gui 命名空间函数 进行控制:

-- 扩展 10 单位血条
local healthbar_node = gui.get_node("healthbar")
local size = gui.get_size(healthbar_node)
size.x = size.x + 10
gui.set_size(healthbar_node, size)

动态创建节点

在运行时使用脚本创建新节点有两种方法. 一种是通过调用 gui.new_[type]_node() 函数. 该函数返回新节点引用以便对其进行控制:

-- 新建节点
local new_position = vmath.vector3(400, 300, 0)
local new_size = vmath.vector3(450, 400, 0)
local new_boxnode = gui.new_box_node(new_position, new_size)
gui.set_color(new_boxnode, vmath.vector4(0.2, 0.26, 0.32, 1))

-- 新建文本节点
local new_textnode = gui.new_text_node(new_position, "Hello!")
gui.set_font(new_textnode, "sourcesans")
gui.set_color(new_textnode, vmath.vector4(0.69, 0.6, 0.8, 1.0))

dynamic node

第二种方法是通过调用 gui.clone() 函数克隆一个已存在的节点或者通过调用 gui.clone_tree() 函数克隆一个已存在的节点树:

-- 克隆血条
local healthbar_node = gui.get_node("healthbar")
local healthbar_node_2 = gui.clone(healthbar_node)

-- 克隆按钮节点树
local button = gui.get_node("my_button")
local new_button_nodes = gui.clone_tree(button)

-- 获得节点树根节点
local new_root = new_button_nodes["my_button"]

-- 向右移动根节点 (及其子节点) 300 像素
local root_position = gui.get_position(new_root)
root_position.x = root_position.x + 300
gui.set_position(new_root, root_position)

动态节点id

动态创建的节点没有id. 设计上就是这样. 引用由 gui.new_[type]_node(), gui.clone()gui.clone_tree() 函数返回, 这是访问动态节点的唯一途径, 记得保留好这个引用.

-- 添加文本节点
local new_textnode = gui.new_text_node(vmath.vector3(100, 100, 0), "Hello!")
-- "new_textnode" 保存新节点的引用.
-- 新节点没有 id, 但是没关系. 得到节点的引用
-- 就没有必要使用 gui.get_node() 函数了.