沙盒引擎教程:从入门到精通
作者:@七海
更新日期:2025年1月
在新页面打开
本教程持续更新。如果不完善、不清楚、或勘误之处欢迎指出(可以直接QQ私聊我)~
本教程分为基础教程和进阶教程两部分。沙盒编辑器内的UI已经足够清晰明确,如果只是基础使用,稍微把玩即可直接上手。本教程主要面向基础使用仍有困难的用户、或希望学习进阶功能的用户。请根据你的需求阅读:
- 基础教程:适用于初次接触、或在使用后仍不理解沙盒编辑器用法的用户。
- 进阶教程:适用于想要实现炫酷效果或高级操作的用户。掌握这部分你就无敌了!
第一章:基础教程
简介
欢迎使用回声岛的沙盒引擎!这是一个专用于回声岛的、由我自己从头实现的一个UI编辑/展示系统,可以帮助 GM 创建几乎任何外观、任何样式的自定义UI。无论你想要制作角色面板、战斗地图还是特殊的游戏道具、可交互的游戏UI,沙盒引擎都能满足您的需求。你的每一个自定义UI的组件都称为一个“沙盒”。你可以:
- 在沙盒编辑器中自由创作沙盒
- 在游戏中,向不同的玩家展示特定的沙盒
- 在游戏中将沙盒快照发送到聊天,这样做可以记录沙盒在不同阶段的状态。
- 为场景绑定沙盒 - 这么做,被绑定的沙盒会直接将UI展示在场景上。通过这种方式,你可以实现对任意场景、任意频道独立地创作UI。
总结来说,沙盒一共有四种展示形态:
形态 | 文本介绍 | 功能 |
---|---|---|
卡片 | 点击沙盒,默认将以卡片形式展示 | 向玩家展示较小的UI |
窗口 | 为沙盒设置窗口模式后,点击将以窗口形式展示 | 向玩家展示较大的UI |
绑定场景 | 将沙盒绑定到某个场景后,跳转到该场景,会将整个沙盒展示在场景上层 | 用于为场景自定义游戏界面 |
快照 | 将沙盒快照发送到聊天后,此快照将始终展示发送快照时的内容。 | 用于保存沙盒的历史记录,在Replay中回放 |
场景绑定
将沙盒绑定场景时,可以选择两种绑定模式:强绑定和弱绑定:
- 强绑定:此模式下,沙盒内的元素将直接以场景图片作为背景,此时,你可以使用沙盒向场景中“添加内容”。例如下图中左侧,将两个角色的图片作为沙盒内容添加到了场景中。
- 弱绑定:此模式下,沙盒和场景实际上是独立的两部分,沙盒将悬浮于场景的上层展示,并可以在观看时自由地缩放、移动。例如下图中右侧,沙盒内容是一个地图UI,独立地浮在场景的上层。
下图解释了这两种绑定模式的区别。
沙盒编辑器的基本操作
要创作沙盒,你需要先学习沙盒编辑器的基本功能。沙盒分为“编辑模式”和“展示模式”。在打开沙盒编辑器后,进入的就是编辑模式。而其它所有情况下,都是“展示模式”。沙盒编辑器的界面有三部分内容:
- 画布:即在编辑模式下,呈现网格背景的部分,这也是沙盒在实际展示时的范围。任何画布内的内容都会被展示,任何画布外的内容都不会被展示。 因此,请合理安排画布大小和节点位置。
- 工具栏:悬浮在右侧。
- 节点:也就是画布上你手动添加的元素内容。
画布操作
- 移动画布:
- 在任何模式下,拖动工具栏上的移动图标即可移动画布
- 在非选择模式下,拖动画布的空白处即可移动画布
- 缩放画布:
- 使用鼠标滚轮进行缩放
- 点击工具栏的 “+” 和 “-” 按钮
- 点击 “⟳” 按钮重置画布的缩放比例和位置
- 画布大小调整:
- 点击工具栏的 “⛶” 按钮设置画布的大小。
请注意:
- 画布的移动和缩放操作是为了方便你在画布上进行创作,不会影响实际展示时的画布位置和大小。
- “画布大小调整”才会改变实际展示时的画布大小,请注意与“缩放画布”的区别。
如何设置合适的画布大小?
在展示模式中,观看者(包括GM和玩家)随时可以自由拖动、缩放沙盒;且沙盒在展示时,画布会默认适应屏幕宽度。因此,无论你的画布实际大小是多大,都可以获得良好的展示效果。所以,在设置画布大小时需要考虑的主要是这两件事:
- 画布比例。这决定了沙盒在实际展示时,画布的宽高比,因此需要优先考虑。
- 沙盒内容的复杂程度。如果你的沙盒中可能出现很小的节点/节点排布过于紧密复杂,请设置较大的画布尺寸,来获得更好的编辑体验。
模式切换(仅PC可用)
- 默认模式: 当工具栏上显示“鼠标指针”图标时,你处于默认模式
- 框选模式: 当工具栏上显示“虚线框”图标时,你处于框选模式
节点操作
画布上展示的每一个元素是一个“节点”。你可添加不同的类型的节点,也可以添加另一个沙盒作为节点。
- 添加节点:点击工具栏最上方的按钮以添加对应类型的节点
- 选择节点:
- 单击选择单个节点
- 按住 Shift 键点击可以选择多个节点
- 使用框选工具(选择模式下)可以一次选择多个节点
- 在默认模式下,按住 Ctrl 键可以直接进行框选
- 在某个节点被选择后,其左上角会出现“节点操作浮窗”
- 移动节点:直接拖动节点到目标位置
- 调整大小:拖动节点四角的控制点
- 删除节点:选中节点后按 Delete 或 Backspace 键,或点击节点操作浮窗的“⋮”按钮并删除
- 复制节点:选中节点后按 Ctrl+C,或点击节点操作浮窗的“复制”按钮
- 粘贴节点:选中节点后按 Ctrl+V,或点击工具栏的“粘贴”按钮
- 全选节点:按下 Ctrl+A
- 节点显示层级调整:在节点操作浮窗中进行:上移/下移/置顶/置底
- 隐藏节点:在节点操作浮窗中进行。被隐藏的节点将不会被展示,但仍在编辑模式下可见(显示为半透明、且自带灰色虚线框),可以随时切换显示/隐藏
- 锁定节点:在节点操作浮窗中进行。被锁定的节点将无法被移动和缩放。可以用于防止节点数量过多时出现意外操作。
- 设置可见玩家:在节点操作浮窗中进行,可以设置哪些玩家可以看到该节点(设置了权限的节点显示为黄色虚线框)。每个沙盒中的每个节点都可以独立设置权限。
- 撤销与重做:点击工具栏中部的左右箭头按钮,或者使用 Ctrl+Z 和 Ctrl+Y 可以撤销和重做上一次的节点移动/缩放操作。
编辑节点
点击节点操作浮窗中的“编辑”图标,你可以进入节点编辑器。节点编辑器提供了各种高级功能,但是在基础使用时,你只需要关注其中三个地方:
- 修改文本:点击后在输入框中输入任意的文本,即可替换节点文本。
- 设置样式:点击后,在弹窗中可以详细定制每个节点的外观:比如字体大小、文字颜色、背景颜色、缩放旋转等属性。
- 预设样式:点击后,在弹窗中可以粗略定制每个节点的外观、动画效果等。这里提供了许多常用的预设样式,你可以进行一键设置。
第二章:进阶教程导览
掌握了基础用法,你就可以像PPT一样自由添加、删除、拖拽、缩放节点——尤其是图片节点,来实现自己想要的各种外观的静态UI。这已经可以满足大部分的演出效果了。在进阶教程中,我们将关注两件事:
- 如何让沙盒应对频繁变化的、复杂的数据。这意味着你所制作的沙盒不仅仅具有视觉效果,同时也兼具了功能性。例如,你希望制作一个自助商店,在玩家声明要购买某个道具之后,你可以非常快速方便地进行沙盒数据的变更(例如:减少商店中的道具数量、增加玩家道具数量、减少玩家金币)。
- 进一步地,如何制作可交互的沙盒。还是上面商店的例子——使用进阶功能,你甚至可以制作一个玩家真的可以自助进行“购买物品”操作的商店沙盒!
本进阶教程将包含以下章节,每个章节的难度和深度逐渐递增。你不一定需要学习每一个章节,根据自己的需求选择性学习即可。但是,不建议进行跳跃性阅读,因为后面的章节往往会依赖前面的章节。
章节 | 介绍 |
---|---|
使用指令按钮 | 插入按钮节点,来实现简单的交互效果 |
使用变量系统 | 动态地改变节点数据,实现功能性UI |
节点编辑器进阶 | 完全操控节点内容,自由创作节点! |
自我复制 | 让单个内层节点在展示时进行自动复制,设计复杂UI的利器! |
使用沙盒节点 | 将另一个沙盒当做节点——实现层次化的UI设计! |
嵌套引用、使用变量按钮 | 使用按钮来实现对变量的实时控制 |
黑盒与参数 | 将沙盒打包成黑盒并发布! |
第三章:进阶教程:使用指令按钮
在工具栏顶部位置,我提供了各种类型的节点供大家选择。其中有两个比较特别的按钮节点:变量按钮和指令按钮。这两个按钮用于实现各种交互式效果。首先让我们来关注指令按钮。
在插入指令按钮时,你需要设置两项内容:
- 按钮文本:可以为空,决定了此按钮显示什么文本内容。
- 指令列表:每行填写一个指令,也可以填写普通的文本消息。
指令按钮的功能非常简单:顾名思义,当用户(包括你自己)点击按钮时,会以其当前身份向聊天中发送对应的内容。例如,你可以制作一个“理智检定”按钮:
- 按钮文本:填写“理智检定”
- 指令列表:仅一行,填写 .sc 1/1d5
保存之后,将其开放给玩家使用(可以手动开放权限、或绑定到场景并切到改场景),玩家只要点击这个按钮,就可以进行理智检定了!
额外注意:指令按钮在编辑模式下点击不会生效。
第四章:进阶教程:使用变量系统
4.1 总览
变量系统是沙盒的核心功能之一。当你不满足于静态的UI时,就需要用它来让数据“变化起来”了!本质上,这一系统的作用是让你可以“更方便的操作沙盒内数据的变化”。请想象一个例子:
你创建了一个血条,希望上面显示的HP数字可以随着玩家的生命值变化而变化。如果没有变量系统,你不得不在每次玩家的生命值变化时,都手动去修改血条的HP数字,导致带团时手忙脚乱。
这时候,就轮到“变量”登场了!要想理解变量系统是如何工作的,你需要想象沙盒是一块“静态显示屏”,用来展示各种数据。不使用变量系统时,每次你想要修改数据,都只能去“显示屏”上手动修改。每个变量都有一个独一无二的名字。“变量”就像是一个个存放数据的“仓库”——有了变量的辅助,沙盒就变成了一块“智能显示屏”,可以根据你的指示,到对应的“仓库”里取出数据,然后再进行展示!
让我们仍然以上面的血条为例子。有了变量系统,你希望沙盒展示的数字就不再是一个固定值,而是:你可以告诉沙盒“请将角色A的HP数值取出来,展示在这里”,请注意这种“取出数据”的操作是始终和数据源同步的——每当该玩家的血量发生变化,这个血条上的数字也会相应变化。而这个“取出数据”的操作,称为“引用变量”。
4.2 引用预设变量
引用变量需要使用特殊的语法,但请不必担心,这并不难。具体来说,沙盒系统已经默认提供了一些预设变量:
- 想要引用角色属性,你需要输入:
${角色.角色名.属性名}
。例如在上面的例子中,你可以用${角色.玩家A.hp}
来表示玩家A的HP值。在进行数据展示时,沙盒会智能地将这部分数据替换为实际的HP值。因此,你可以将某角色在沙盒中可能用到的数据都扩充在其角色卡的.st字符串中 - 引用当前频道名:固定值:
${当前.频道}
- 引用当前场景的图片链接:固定值:
${当前.场景图}
- 引用当前场景的名字:固定值:
${当前.场景名}
- 引用当前正在发言的角色名字:固定值:
${当前.发言者}
- 引用当前打开回声岛的角色名字:固定值:
${当前.观看者}
。此预设变量一般用于:希望不同的玩家看到同一个UI时,可以各自看到不同的内容。
关于使用变量的一些额外说明:
- 你可以将上述的引用语法填入任何你需要的地方。
- 除了控制文本变化以外,也可以控制其他任何支持“输入内容”的属性的变化。
- 变量引用的前后可以衔接正常文本内容。例如,角色A的hp为12时,
我的HP是${角色.角色A.hp}点
将会展示为我的HP是12点
。
下面是使用目前学到的关于变量的知识,实现一个血条的极简demo:
(请忽略样式,此处以教学演示为主。实际使用时你可以将所有元素替换为图片或修改样式来进行美化)
4.3 自定义变量
你可以这么简单理解自定义变量的功能:它允许创建一个Excel表格,并引用其中的数据来在沙盒中展示。
- 创建自定义变量
预设变量让你可以访问部分回声岛游戏房间中的数据。但大部分情况下,由于每个人的实际需求各不相同,你可能更需要创建自定义变量。相比起直接使用预设变量,自定义变量多了“创建”的过程:你要先手动创建自己的“数据仓库”,才能在沙盒中取用。
在定义每个变量时,你需要分别指定每个变量的名字和内容(值)。变量名必须独一无二,否则会造成歧义。在指定变量值的时候,回声岛提供了所见即所得的表格编辑器——你可以将数据以类似Excel的方式来填入其中!
如果你的变量不是表格数据,例如你只希望在变量中存储一个数字或一段文本,请使用“YAML编辑器”,直接输入你想存储的内容即可。如果你不知道YAML是什么,将其当做“一种直接编辑数据本身”的方式就好。如果你更熟悉YAML语法,也完全可以使用YAML来代替表格编辑器。如果你希望学习YAML的具体写法,请上网自行搜索教程。
请额外注意,为变量起名时,名字只能包含中文、数字、字母、下划线,且不能以数字开头。对于中文名字,你不能使用下面这些词语作为变量名:“变量”、“角色”、“当前”、“频道”、“循环”、“序号”、“场景”,因为这些名字已经在预设变量中被占用。
- 引用自定义变量
自定义变量的引用方式与预设变量完全相同。对于某个自定义变量,你可以使用${变量.变量名}来访问它本身。进一步地,如果你想访问的表格数据其中的一个元素(而不是这个变量整体),可以直接选中某个单元格,复制“使用此数据”中的内容使用即可。
请观看下面这个演示视频,其中演示了如何创建一个表格数据变量、并访问其中某一个单元格的内容。
使用自定义变量有一个显而易见的好处,那就是:你可以将所有需要频繁变动的数据都定义在一个地方——这样就不需要在需要频繁修改时,去各个节点当中去搜寻了。 不过你现在可能也会疑惑—— 听起来很不错,我可以在沙盒中展示自定义的表格数据。但是假如表格很大,在引用这些数据时,岂不是需要一个一个填写对每个单元格的引用?这岂不是很麻烦?别担心,在后续的章节中,我们将解决这个问题。
- 选读:理解变量引用语法
在使用变量时,你用到的${变量.变量名}
这种语法并不难理解。具体来说,最外层的是${}
是固定存在的,用来区别于其他普通的文本内容;而在大括号当中,固定是aaa.bbb.ccc
这样的形式。在这里,点符号表示“取出”操作,这种连续的结构表示的是“依次取出”。
在取出一个表格元素时,我们需要先取出行数据,后取出列数据。表格只有行名而没有列名,因此在取出行数据时,我们需要使用序号来表示“要取出的行”。这个序号从1开始自增。因此,${变量.商店数据.1.名称}
表示的就是“取出用户的自定义变量中,叫做商店数据的表格中,第一行项目里的名称一列”:
- “变量”表示引用的是用户自定义的变量,而不是预设变量。
- “商店数据”表示要取出“商店数据”这个变量
- “1”表示取出商店数据的第一行(序号从1开始计算)
- “名称”表示取出第一行的项目的“名称”这一列的内容
4.4 使用全局自定义变量
有时,你的多个沙盒可能需要共享同一份数据(同一份自定义变量)。为了处理这种情况,我设置了“全局自定义变量”这一特性。在房间内的游戏编辑器(刷子按钮)中,你可以在“变量”区域选项下,定义房间级别的全局自定义变量。此处定义的变量可以在当前房间内的任意沙盒中引用。具体的引用方式和沙盒内的自定义变量只有一处不同,其写法为:${全局.变量名}
- 即用“全局”来替换“变量”字样。
4.5 在角色卡内自定义变量
你可能注意到了,在角色卡界面中也有一个“自定义变量”部分。这是因为:有时你可能需要为游戏中的角色或玩家设计某些属性。例如制作一个玩家背包,在其中保存玩家所拥有的物品数量等。此时,这些属性实际上是和某一个角色绑定的。此情况下,你可以直接在角色卡当中自定义变量。在此处定义的变量可以通过${角色.角色名.变量名}
来引用,即,引用方式和引用st字符串中的属性一样。
第五章:进阶教程:节点编辑器进阶
接下来,让我们暂时离开变量的世界,先来学习如何使用节点数据编辑器,实现更精细地控制沙盒内容。虽然我已经提供了一些预设类型的节点,但它们可能无法满足你的需要。没关系!其实,每一个节点都是可以自定义的,这一过程通过节点编辑器来实现。在基础教程中,我们只关注了节点编辑器中的“更改文本”、“预设样式”和“编辑样式”这三项内容。在这一章节,我将会教你节点编辑器当中所有功能的用法。
5.1 节点的层次
具体来说,在沙盒中直接看到的“节点”并不是你可以控制的最小单位,每个节点实际上都是一个容器,具有容纳其他节点的能力。在每个节点内部,你都可以新建新的节点。你可以想象节点像是一个个“盒子”——一个大盒子中可以装着若干小盒子,每个小盒子里还可以继续装着更多更小的盒子。鉴于这种“包含”的关系,节点实际上是有不同层次的。因此我们将用不同的名字来区分不同层次的节点:
- 如果一个节点A内部容纳着若干节点B, C…,那么B, C…称为节点A的“内层节点”;节点A称为B, C的“外层节点”。
- 此时,节点B和C位于同一个层次(第一层)。
- 自然地,假如节点B内部包含节点D, E…,则D, E既是节点B的内层节点,也是节点A的内层节点。
- 此时,节点D和E也位于同一个层次(第二层)。
- 在沙盒中可以直接看到、直接拖动的节点称为“顶层节点”,位于“最顶层”。
上面的例子如下图所示。根据下图,你可以更容易理解节点之间的层次和嵌套关系:
5.2 节点编辑器
以下是节点编辑器每个功能区的介绍:
- 展开/收起当前节点。
- 更改节点类型。
- 为当前节点添加备注,此备注仅你自己可见。这功能仅仅是为了在节点数量过多时,不至于过于混乱。
- 高亮当前节点。此功能仅对内层节点生效。点击顶层节点的“高亮节点”按钮将会取消内层节点的高亮显示。
- 在当前节点下新建内层节点。
- 复制当前节点数据。
- 将复制的节点数据粘贴到当前节点(进行覆盖)。
- 预览区。只有顶层节点有此功能 - 你对节点的所有操作都会反映在这里。但偶尔可能会出现预览区与沙盒中的实际节点外观略有不匹配的情况,请以沙盒中的外观为准,此处预览仅供参考。
- 节点设置区。你可以在此编辑当前节点的属性。其中最重要的三个部分是:“节点数据”、“节点样式”和“预设样式”。
- 内层节点列表。除了没有预览区以外,每一个内层节点编辑器的结构和顶层节点完全相同。
使用节点编辑器对顶层节点进行编辑时,往往需要创建嵌套的内层节点。创建后,你可以继续为每个新节点设置属性、并为每个内层点继续嵌套创建新的内层节点。默认情况下,创建的内层节点会从上到下依次排列。但也可以通过“预设样式”中的“布局方式”来改变这一行为,来实现其他的排列方式。每个节点都可以自由地改变类型 - 通过这种方式,你可以深度定制每个顶层节点的外观和结构。
对每个节点,有以下几个类型的项目可以设置:
- “节点数据”、“节点样式”、“预设样式”;这三个属性所有节点都有,并且是最重要的三部分。
- “背景图片”、“修改文本”;这两个属性有的节点没有。
- 以上内容统称为“节点属性”。
5.3 节点数据
“节点数据” 控制了传递给节点的数据。这些数据往往决定了节点的内容:例如对图片节点,你需要在“节点数据”中指定图片资源的链接;有时,“节点数据”也会决定节点的外观:例如在立绘节点中,你可以修改“节点数据”中的“尺寸”项目,来改变立绘的大小。对于不同种类的节点,其“节点数据”内的项目都各不相同,你需要根据实际节点类型和你的需求来进行设置。
5.4 节点样式 / 预设样式
点击“节点样式”按钮,你可以在其中精细地控制当前节点的外观 - 包括且不限于颜色、字体、边框、透明度、缩放等。而在“预设样式”中,包含了一系列我已经制作好的样式效果,包括且不限于:根据当前主题智能地改变前景/背景颜色、圆角大小、阴影程度、动画效果等。灵活地设置“节点样式”和“预设样式”可以让你的节点更加个性化,具有更加炫酷的视觉效果。
以下是一个例子,通过纯节点操作实现一个简单的时钟。同样请注意,在实际使用中,如果你只是想实现一个这样的时钟,并不需要用到进阶功能,直接将多个顶层节点组合即可。此教程仅用作演示用途。
第六章:进阶教程:自我复制
到现在为止你已经学会了变量系统和节点编辑器的基本操作。接下来我将介绍将二者结合起来的重要功能 - 自我复制。这一功能允许用户在节点编辑器当中,仅仅创建一个内层节点,但是将这个节点用特定的数据,在同一层次复制若干份。重复性数据是非常常见的。例如以下三个例子:
- 你想为团里每个玩家做一个血量指示器;
- 你想做一个商店UI,其中每个格子是一个商品;
- 亦或者在上一节视频里的时钟案例中——你可能不止想要“天气”和“时间”,而是想要更多联排的内容。
在这些情况下,你都可以使用自我复制来实现。因为这几个例子的本质都是“相同的UI里填充了不同的数据,并进行了多次重复”。让我来逐个解释:
- 本质上,每个玩家的血量指示器的UI设计是相同的,只是其中填充的数据不同:例如头像图片、玩家名字、具体血量等,并且这样的UI重复了多次。
- 本质上,每个商店格子的UI设计是相同的,只是其中填充的数据不同:例如商品图片、商品名称、价格等,并且这样的商品格子重复了多次。
- 本质上,时钟里的每个项目的UI设计是相同的,只是其中每个项目的大字和小字内容不同,并从左到右重复了多次。
因此所有类似这样的需求,都可以通过自我复制来非常方便地实现。如果不使用自我复制,你将不得不新建很多个UI —— 例如,你的商店中有20个商品,你只能手动将商品格节点(甚至可能不止一个节点)复制20次,并在需要变更数据时手动修改。而使用自我复制,你只需要在节点编辑器中的“自我复制”属性中,定义你的UI在每次自我复制时所需要的数据,沙盒引擎在展示时,就会自动地将其进行复制!
让我们仍然以商店格子为例子来进行解释。首先,商店的主体应当是一个顶层节点,其中的每个格子都是内层节点。假如你想设置五个格子,你并不需要真的手动创建五个节点 —— 而是只创建一个内层节点,并设置其“自我复制”属性,让其自我复制五份即可。
这里的复制规则是:你需要在“自我复制”中填写一个列表数据(当然,表格数据本身也是列表数据,所以你完全可以使用直接使用表格编辑器)。节点会在每次自我复制时,分别取用其中的一项数据来进行复制。要想引用被取用的数据,需要使用一个临时变量:${变量.循环}
。请注意,此临时变量只有在设置了“自我复制”的节点,及其内层所有节点中可用。请观看下面的演示视频,仍然以商店为例子,来了解具体的操作方式:
关于此功能的一些额外说明:
- 顶层节点不能设置“自我复制”属性。
- 在执行了“自我复制”的内层节点当中,你还可以通过
${变量.序号}
来引用进行自我复制时,当前所取用的数据在表格中的序号(行号)。
只要你发现有任何“UI在重复,只有数据在变化”的情况,都可以使用“自我复制”功能来实现。上手试试吧!
如何制作复杂节点(一)
要想使用节点编辑器制作复杂节点,你需要先在脑中明确内层节点之间的层次关系。实际的操作已经在上面的视频体现,这里让我解释一下“方法论”层面,制作一个复杂节点需要哪些步骤。
- 首先需要根据“外层节点包含内层节点”的关系来确定你的UI需要分为几层、每一层分别是什么含义。一般来说,有“几次包含关系”,就有几层。
- 先在节点编辑器中建立大致的层次关系,并为每个层次的节点命名,以免混乱。
- 明确哪些层次中,会出现“重复的UI”。在拥有“重复UI”的层次上创建自我复制的内层节点,并先填充一些伪数据——最后再将其替换为实际要用到的数据。
- 从顶层节点开始,确定每一层节点需要使用哪种布局方式。布局方式的选择非常重要,规定了节点的内层节点如何排列(默认是从上到下)。你需要在节点编辑器的“预设样式”中设置“布局方式”。
- 最后,再为每个节点设置样式、并替换自我复制时需要用到的数据(如果有)
但是,如果你使用节点编辑器不熟练,可能会觉得这种完全使用节点编辑器进行布局的方式很繁琐。在下一章,我们还将介绍另一种较为简单的方式。
第七章:进阶教程:使用沙盒节点
在这一节,我将教你一个有用的功能:将另一个沙盒作为节点来使用,并教你使用沙盒引擎时应该遵循的一个重要原则:层次化。灵活使用这一功能,可以大大减少重复工作量。
7.1 沙盒节点:嵌套沙盒
你可能注意到,在工具栏顶部的插入节点类型中,有一个“沙盒节点”。没错,这指的是:你可以将另一个沙盒当做节点来插入!通过这种方式,你可以实现沙盒的嵌套-就像节点编辑器中,节点可以相互嵌套一样。我们将当前正在编辑的沙盒称为“主沙盒”。内部插入的沙盒称为“沙盒节点”。你可以在节点编辑器内部,将任意层次的节点转变为“沙盒节点” - 这意味着,你可以将另一个沙盒插入到当前沙盒的任何层次中,包括顶层和任意内层。这种插入沙盒的行为我们称为“引用沙盒”。其具有和“引用变量”类似的性质 - 当原始沙盒的数据发生变化时,所有引用了它的地方,数据也都会自动变化。
7.2 嵌套沙盒中的变量引用
你已经了解了如何引用在当前沙盒中定义的变量。当我们使用嵌套沙盒时,是有办法引用另一个沙盒中的自定义变量的 - 但是这种跨沙盒的变量引用有一些限制。具体来说,假设我们有一个主沙盒A和沙盒节点B,跨沙盒的变量引用有以下规则:
- 在A中无法引用B中的自定义变量。
- 在B中可以直接使用A中的自定义变量。只要打开B的沙盒编辑器,直接引用A中定义的变量即可。当然,由于B实际上并没有定义这些变量,此时会出现错误信息(例如这样的内容:
${变量未定义}
),这是正常的,请不必担心。当你将B作为沙盒节点插入A当中后,B才可以访问到A的自定义变量,此时渲染结果就会变得正常了。(关于此内容,请看本章结尾处演示视频的01:21~03:00)
7.3 层次化设计
什么叫层次化呢?这指的是,在你设计UI时,需要从整体的视角来决定设计方案、而不是仅仅从局部的视角来考虑,并尽可能地将所有“重复使用”的部分作为一个单独的沙盒。让我们举个例子:
- 例子:假设你正在带一个PVP秘密团,并希望通过绑定场景的方式来展示房间UI。你创建了3个秘密频道——并分别为场景绑定了三个沙盒,提供给三队不同的玩家进行游戏。这时,你想在这三个不同的沙盒中都展示一个积分榜,来告诉三队玩家当前的比分情况。
- 直白、但不推荐的做法:你当然可以在三个沙盒中分别创作三个一模一样的积分榜,但是每当你想改变积分时,就麻烦了:你将不得不每次都对三个积分榜进行数据修改。
- 推荐做法:单独做一个“积分榜沙盒”,并在三个沙盒中分别引用它。
让我们使用层次化的视角来理解这个例子:
- 在设计时,你注意到“积分榜”这个内容在多个沙盒中会重复出现,且使用的是共通的数据。
- 因此,使用单独的“积分榜沙盒+引用”的方式来进行实现。在三个频道的沙盒中,分别将这个“积分榜沙盒”作为沙盒节点添加。
- 每次修改积分时,只需要在“积分榜沙盒”中进行一次修改即可。它对应的所有“沙盒节点”都会自动地更新!
7.4 如何制作复杂节点(二)
使用沙盒节点,可以更加轻松地制作单个复杂节点。还记得我们之前“制作复杂节点”的教学吗?当你面临需要执行“自我复制”的内容时,将不得不手动使用节点编辑器来创建复杂节点 - 这一过程并不轻松,因为你需要精心设计每个节点的样式和布局,才能让所有元素都位于满意的位置。
使用沙盒节点,可以解决这一烦恼:你可以将任意层次的内容单独制作为一个独立的沙盒,并在当前沙盒中、对应的层次上引用它即可。由于沙盒节点中可以直接引用主沙盒的变量,你无需重复定义同一份变量。请看下面这个视频,来理解这一过程。
两种制作复杂节点的方式的优劣对比:
- 使用节点编辑器:操作麻烦,但性能更好(不会导致卡顿),且变量管理方便(始终都在同一个沙盒中)
- 使用沙盒节点:操作简单,但性能更差(可能导致卡顿),且变量管理较为复杂(会分散在多个沙盒中)
7.5 重要事项
- 请不要在插入沙盒节点、选择沙盒时,选择当前沙盒自身 - 即试图“把沙盒A插入沙盒A”,这会导致产生错误。
- 节点可以多层嵌套,但是请勿嵌套过多层沙盒,这可能会导致性能问题。
- 同理,请谨慎使用沙盒节点的自我复制。沙盒节点过多时,可能会导致性能问题。
第八章:进阶教程:嵌套引用、使用变量按钮
最后,让我们介绍另一种特殊节点:变量按钮。它的功能是非常简单的——在使用时,需要填写按钮文本、想要修改的变量名、以及想要修改的新值,在点击按钮以后,对应的变量值就会相应地修改。和自定义变量相搭配,你可以实现一些简单的交互式组件。例如,你可以按照下面这个视频的做法,设置一个极简的战斗轮指示器:
以上就是变量按钮的基本使用方法,非常简单。请额外注意:
- “变量名”输入框要填写的是“变量的名字”,而不是“变量的引用” - 即,不需要填写
${变量.我的变量名}
,而是直接填写“我的变量名”。这一过程是在指定“点击按钮以后,你想要改变谁的值”。 - “变量名”输入框内,也允许填写一个复杂变量的子元素,例如一个表格变量的某个单元格。例如:有一个表格变量“我的表格”,填写“我的表格.1.价格”是可以的,此时,点击变量按钮以后,值会发生变化的就是某一个特定的单元格。
- 变量按钮在沙盒的编辑和展示模式下都可以点击;只要玩家可见该按钮,玩家也可以点击。但是:只有GM在编辑模式下点击变量按钮、并保存沙盒以后,会实际影响房间数据、并同步到玩家;其他情况下的点击均不影响房间数据。(这也很好理解,在展示模式下,对变量按钮的点击实际上是在“使用UI”,而显然,每个人应该能各自独立地使用UI,而不是强制和GM同步)
以下我将介绍一种高级用法:结合嵌套引用和变量按钮,来实现按下按钮之后,为某个UI“换数据”的效果。
选读:嵌套引用
在阅读本小节之前,请确保你也已经阅读并理解了【自定义变量】一章中的【选读:理解变量引用语法】内容。
你现在已经了解了变量引用的基本语法,让我们先回顾一下,格式是:${变量.变量名.子元素.子子元素...}
这样的语法,并且点符号表示的是“取出”操作。所谓的嵌套引用就是——你甚至可以用另一个变量来表示“想要取出的是什么内容”。这听起来有点复杂,实际上很好理解。“变量引用”的本质是一种“标记”。例如,你有一个表格变量“商店数据”,那么${变量.商店数据.1.价格}
是在告诉沙盒引擎“给我把商店里第一行的价格取出来放在这里!”。而嵌套引用本质上是——当“去哪里取数据”这件事情也是动态的时候,允许你用另一个变量来告诉沙盒 “我要去哪里取数据”。例如,使用嵌套引用,你可以:
- 先定义一个用于辅助的自定义变量,例如叫做“当前商品”,假设其初始值是233。
- 用这个辅助的自定义变量来代替变量引用内部的内容,例如:
${变量.商店数据.${变量.当前商品}.价格}
,也就是在变量引用当中又嵌套了一层引用。
让我来逐步解释,当你引用${变量.商店数据.${变量.当前商品}.价格}
时会发生什么:
- 沙盒引擎会先取出变量“商店数据”中的数据
- 沙盒引擎想要获取下一步的“取出”指示,它发现这个“取出指示”是
${变量.当前商品}
——这竟然是对另一个变量的引用!于是它会去先解析这个嵌套引用的实际值,也就是233。 - 此时,这个引用就等价于:
${变量.商店数据.233.价格}
了。
这个功能在正常情况下,可能不会有太大用处。但是,只要结合变量按钮,就会非常强大:还记得吗?变量按钮允许你通过点击来改变任意变量的值。于是,你可以直接使用多个变量按钮来控制“当前商品”这个自定义变量的值!例如在这个例子中,你可以设置两个变量按钮,让它们的行为分别是:
- 点击按钮A,让“当前商品”变成233。
- 点击按钮B,让“当前商品”变成234
这样一来,就可以实现可以点击交互的UI了!让我们通过下面这个视频,来了解具体操作。视频当中实现了一个极简的“线索切换器”。
使用这种模式,你可以实现类似“翻书”的效果。数据来源的表格是“书本”,每一行就是“每一页”,而辅助变量则是“页码”。请记住这种感觉,因为所有在逻辑上等价于“翻书”的功能,都可以通过这种方法来实现。但此时,你可能还会疑惑:假如我的“书本”有100页,难道我只能创建100个变量按钮,来控制“页码”的不同值吗?不必担心,我早有准备!在变量按钮中,如果所控制的变量类型是数字(例如视频中,变量N就是一个数字),你可以用下面这两种特殊的标记来表示“为该变量加减某个数字”。其具体写法是:
- 在“新值”输入框填写
(add-数字)
,例如:(add-1)
。此时变量按钮的功能是:为变量的值增加对应的数字 - 在“新值”输入框填写
(sub-数字)
,例如:(sub-2)
。此时变量按钮的功能是:为变量的值减去对应的数字
第九章:进阶教程:黑盒与参数(选读)
到此为止,你已经学会了使用沙盒编辑器创作UI的几乎所有知识。在这一章节中,我们要学习一个新的概念:“沙盒参数”。
你可能注意到,在之前的“沙盒节点”教程中,当你在主沙盒A中引用沙盒B,并希望让B中的节点使用A当中的变量时,沙盒B本身会出现报错信息 - 因为被引用的变量存在于沙盒A中,而不存在于沙盒B中。即,B的展示是依赖于A的。当B独自展示时,是一个没有任何意义的沙盒(具体请看第七章结尾处演示视频的01:21~03:00)。
而使用“沙盒参数”功能,你可以做到:让沙盒B在不依赖任何其他沙盒的情况下,也可以被引用。即,沙盒B既可以独自展示、也仍然可以作为沙盒节点插入其他任意沙盒。
9.1 概念理解
而所谓“参数”,是指指定一批自定义变量,允许其他沙盒在使用时覆盖它们的值。让我们通过一个具体的例子来理解这一点。假设你的沙盒B是一个"角色卡片"沙盒,其中,角色的名字、等级和职业分别是三个自定义变量。在没有参数功能时,如果你想在其他沙盒A中使用它,B无法独自展示,只有被插入A中时才能正常展示。而使用参数,你可以:
- 在制作沙盒B时,将"角色名字"、“角色等级”、"角色职业"设置为参数(需要注意,参数是从自定义变量中挑选出来的)
- 在沙盒A中引用B时,用A当中的变量覆盖这些参数的值。
- 沙盒B也可以单独展示,此时,它会使用默认的自定义变量值而不报错。
这样一来,你的"角色卡片"沙盒就既可以独立使用、也可以在任意沙盒中引用。我们把这种带有参数的沙盒称为"黑盒";而“设置参数”的过程,也叫做“打包黑盒”。黑盒具有如下性质:
- 它可以独立运行,不依赖于其他沙盒
- 在独立运行的同时,也可以被其他任何沙盒引用和使用
- 使用者只需要关心如何修改参数,而不需要关心内部是如何实现的
- 进一步地,黑盒像帖子一样,可以发布到社区中,供你自己在其他房间、或其他人使用。
9.2 打包黑盒:实操
在沙盒编辑器中,工具栏的最底部有“打包与发布”按钮,你可以通过它来将当前沙盒变为一个黑盒。打包黑盒的过程也就是设置参数的过程。观看下面这个视频中,来了解如何进行设置参数的具体操作、以及如何使用打包后的黑盒。
9.3 发布和使用黑盒
黑盒的另一个用处是:当你制作了一个实用的黑盒后,可以选择将它分享到社区中。在“打包与发布”界面的“发布新版本”功能区进行操作。在这里你可以将打包好的当前沙盒发布到社区中,也可以在后续持续更新该沙盒的不同版本。此部分毫无难度,因此仅介绍一些注意事项:
- 发布前,请将必要的自定义变量转变为参数,以便后续使用时,可以替换其中的数据。
- 请对参数的名称、帮助说明、以及沙盒本身的名称、介绍内容进行补充,以免造成歧义或误用。
- 版本号必须遵循类似“1.2.3”的格式:含义为“主版本号.次要版本号.补丁版本号”
- 请只在必要的时候发布新版本。沙盒社区的结构类似区块链,一旦发布便直接归档、不可删除。为了防止沙盒版本过多造成混乱,请不要过度发布。
如何使用其他用户发布到社区中的黑盒:在你插入节点时,会看到“选择社区沙盒”选项,进入选择即可 - 就像引用你的其他沙盒一样简单。此处不赘述。
使用建议
- 强烈建议在备团阶段完成所有沙盒的制作,并尽可能地在游戏过程中只操作变量、指令按钮、变量按钮这三部分内容,否则有可能影响最终的Replay效果。如果你不关心最终Replay效果,可以忽略这一点。
- 合理规划画布大小和节点位置,避免内容过于拥挤或分散。
- 尤其注意设置合适的画布大小,画布大小的设置非常影响最终的展示效果。
- 建议为重要的节点起名字,防止节点过多时难以区分和辨认。
- 当沙盒绑定场景时,强烈推荐GM和玩家都使用电脑进行游戏。手机端虽然也进行了完善的支持,但是毕竟屏幕太小,观感难免较差。
- 如果此情况下一定要用手机,强烈建议将手机横屏使用。
- 合理地在“通过组合节点来实现UI” 以及“通过节点编辑器来实现UI” 两种操作中权衡:
- 前者创作起来很简单,但是可能造成节点数量过多,后续维护和编辑困难 - 例如,假如你希望制作一个表格,使用此方式,你将不不为每个表项创建一个新节点,这会导致编辑和拖拽都不方便,后续在渲染时也会产生性能问题;
- 后者有一定的创作门槛,但是可以以单个节点的方式实现复杂的UI,后续维护和编辑也会非常方便。例如你希望制作一个表格,直接将节点类型改为文档,并直接编辑其文档内容即可。
- 请务必时常点击保存,避免数据丢失。