Defold 提供了 GUI 编辑器以及与之配套的脚本用以实现用户界面.
Defold 的图形用户界面是被放在集合里的, 依附于游戏对象的 GUI 组件. 这种组件有如下特点:
界面独立于游戏内容. 所以集合编辑器里并不显示界面元素. 但是界面必须依附于一个游戏对象而这个游戏对象要被放在集合里. 具体放在集合什么位置上并不影响界面的位置.
GUI 的创建基于一个模板文件. 要新建GUI文件, 在 Assets 浏览器中 右键点击 然后选择 New ▸ Gui. 为文件命名然后点击 Ok.
Defold 会自动启动场景编辑器打开这个文件.
大纲 视图里列出了所有 GUI:s 内容: 节点及其资源列表(见下文).
中间编辑区显示 GUI. 右上角的工具栏有 移动, 旋转 和 缩放 工具, 以及一个 布局 选择器.
当前布局用白色方框表示, 其宽度高度是在项目配置文件里设置的.
在 大纲 视图中选中根节点 “Gui” 就会显示出当前GUI的 属性:
Per Node
当父节点或屏幕大小改变时, 调整各个节点大小.Disable
关闭调整. 各个节点保持不变.界面的结构与集合不同, 是分门别类的. Outline 视图中可以看到所有资源都被按照其类型分配到 “子文件夹” 下:
要添加资源, 右键点击k Outline 里的 “Gui” 根节点, 然后从上下文菜单中选择 Add ▸ [资源类型].
也可以在相应类型文件夹上 右键点击 然后选择 Add ▸ [资源类型].
界面有节点组成. 节点是一种类似游戏对象的元素. 可以进行位移 (移动, 旋转和缩放) 并且以父子树形结构排列. 有以下几种节点类型:
右键点击 Nodes 文件夹选择 Add ▸ 然后点击 Box, Text, Pie, Template 或 ParticleFx 即可创建节点.
还可以用快捷键 A 来创建节点.
节点有自身属性:
Manual
. 节点尺寸决定了节点接收输入操作的范围. 此值也可使用脚本动画进行控制.Automatic
则自动计算并设置节点尺寸. 如果设为 Manual
则需手动设置节点尺寸.gui.pick_node()
返回节点. 可以使用 gui.set_enabled()
和 gui.is_enabled()
函数手动打开或检查该属性.gui.pick_node()
返回节点. 可以使用 gui.set_visible()
和 gui.get_visible()
函数手动打开或检查该属性.0
无空白. 默认值为 1
.Alpha
覆盖下层颜色. 有的软件将其称作 “普通” 混合模式.Add
叠加下层颜色. 有的软件将其称作 “增强” 混合模式.Multiply
与下层颜色相乘.Screen
将节点的像素值与背景成反比. 这种混合模式在图形软件中称作 “Screen”.可选值有 Center
, North
, South
, East
, West
, North West
, North East
, South West
和 South East
.
如果修改了节点的轴点, 节点会适当移动以保证坐标位置不变. 对于文本节点来说 Center
意味着文字居中对齐, West
意味着文字左对齐, East
意味着文字右对齐.
可选值有:
None
(X轴 和 Y轴) 相对于窗体或者父节点的中心, 保持自身位置.Left
或 Right
(X轴) 缩放水平方向位置以便保持其相对于窗体或者父节点宽度方向上的百分比位置不变.Top
或 Bottom
(Y轴) 缩放垂直方向位置以便保持其相对于窗体或者父节点高度方向上的百分比位置不变.这里有一个节点放置在逻辑分辨率为横屏的场景中:
当场景需要填充竖屏时. 每个节点都会被拉伸. 但是如果使用了适当的调整模式, 节点内容的长宽比可以保持不变. 可选值有:
Fit
缩放节点内容,使其等于拉伸的边界框宽度或高度, 以数值最小者为准. 换句话说, 内容将拉伸到父级的边界.Zoom
缩放节点内容,使其等于拉伸的边界框宽度或高度, 以数值最大者为准. 换句话说, 内容将超越过父级的边界.Stretch
拉伸节点内容, 使其填充父级的边界框.如果场景的 Adjust Reference 设置为 Disabled
的话, 此设置被忽略.
None
正常渲染.Stencil
以当前节点边框作为子节点蒙版.详情请见 GUI 蒙版教程
轴点, 锚点和调整模式互相配合可以给设计者很大的发挥空间. 但是但凭想象很难搞清楚它们对应的具体功能. 这里列举了一个具体的例子, 屏幕分辨率 640x1136 的界面:
界面的 X 和 Y 锚点为 None 调整模式为 left. 上面板轴点为 North, 下面板轴点为 South 上面版里的进度条轴点为 West. 其他节点轴点都为 Center. 如果把窗体拉宽, 看看会发生什么:
如果我们希望上下面板保持屏幕宽度要怎么做? 可以把两个面板的调整模式设置为 Stretch:
出不多了. 上下两个面板会拉伸并一直保持屏幕宽度大小, 但是进度条和下面版的内容位置不太对. 要是想让进度条于上面版左对齐, 修改 X 锚点为 Left:
上面版完美了. 进度条本身轴点是 West 也就是说让它们的左端 (轴点) 与父级面板左边缘 (X 锚点) 对齐.
然后再把下面版左边方块的 X 锚点设置为 Left, 右边方块的 X 锚点设置为 Right, 就会变成这样:
结果还是不太对. 我们想让两个方块分别呆在下面版的左右两端. 但是轴点搞错了:
两个方块的轴点都是 Center. 也就是说当窗体变宽时方块的位置 (轴点) 处于相对于边缘的固定位置上. 本例中左边方块在 640x1136 分辨率窗口中大约位于离左边界 17% 的地方:
屏幕缩放时它保持这个 17% 的位置:
如果把左边方块轴点设为 West, 右边方块设为 East 结果就是我们想要的样子了:
节点基于 “Nodes” 文件夹的排序进行绘制. 最高处节点最先绘制, 也就是会被放置于其他节点的后面. 最下面的节点最后绘制, 即它会位于其他节点前面. 至于节点 Z 值并不影响绘制顺序; 但是记得如果Z值超过了渲染脚本的渲染范围就不被渲染了. 可以使用层来覆盖这个默认的绘制顺序 (见下文).
选中节点按 Alt + Up/Down 移动其在列表中的排序.
排序也可使用脚本控制:
local bean_node = gui.get_node("bean")
local shield_node = gui.get_node("shield")
if gui.get_index(shield_node) < gui.get_index(bean_node) then
gui.move_above(shield_node, bean_node)
end
把节点拖放到另一节点上就组成了一个父子结构. 子节点基于父节点轴点继承父节点的位移 (位置, 旋转和缩放).
父节点先于子节点进行绘制. 使用层可以改变这个顺序还可以优化性能 (见下文).
Layers 可以方便控制节点绘制顺序以及减少draw call. 引擎绘制界面前, 会根据以下规则合批渲染:
如果有一条不符合, 就会破坏合批产生另一个 draw call. 蒙版和被蒙节点必然会破坏合批产生draw call.
树形结构对于节点管理非常方便. 但是不同类型节点的混合一定会打破合批渲染:
渲染管线被迫为不同类型的节点建立不同的渲染批次. 这三个按钮就会产生6次 draw call.
要是使用层, 就可以重塑节点的绘制顺序, 渲染管线就能更好地进行合批减少 draw call. 第一步新建层. 在 Outline 的 “Layers” 文件夹上 右键点击 然后选择 Add ▸ Layer. 在 Properties 视图中填充 Name 属性给层命名.
现在给每个节点的 Layer 属性都分配适当的层. 层的绘制顺序优先级高于默认情况, 所以把按钮底图都分配给 “graphics” 层, 文本节点都分配给 “text” 层, 那么界面绘制的顺序就是这样的:
先绘制 “graphics” 层里的节点:
再绘制 “text” 层里的节点:
这样一来合批就成形了, 不再需要那么多 draw call 了!
注意如果子节点没有设置分配层默认继承分配父节点所在的层. 没有设置分配层的节点会被归为 “null” 层, 这个层最先被绘制.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB