Data Studio——创作界面
Data Studio 是一个能完成所有事情的窗口:查找、搜索、单元格编辑、行/列/标签页的创作、工作表的创建与删除,以及一个能展示一条记录由什么构成的记录画布。
其底层规则始终不变:工作表具有权威性。Studio 只会写入来源(本地文件 / Google 工作表),绝不会写入 SO,并且每一次更改都要经过一次自动重新导入来确认。
Tools ▸ SheetForge ▸ Data Studio 会打开它——菜单中唯一的创作入口。它不需要任何插件:下文的一切仅凭核心内置类型就能工作,插件则会在此之上叠加形状和只读的键空间(见有插件和没有插件)。
只有一个创作窗口。更早的工作台(Workbench)——最初的 IMGUI 窗口——已经被移除,它曾经能做的一切,Studio 现在都能做。如果你正在升级,请参见工作台发生了什么。
屏幕上有什么
顶部工具栏
- 当前激活来源的标签会显示供应方名称;没有活动设置时会变暗。
- ↓ Pull from source 会执行一次导入。
- ↑ Push to source 带有一个统计待处理更改数量的小标签。
- 旁边的 Discard 按钮会丢弃窗口中暂存的每一处更改。它会先给出一次带数量说明的确认,并作为单个
Ctrl+Z步骤执行,因此就算不慎点了丢弃,暂存内容也还能恢复。来源本身绝不会被触及。 isolated/draft徽标。- ⛔/⚠ 计数器。点击计数器会跳转到第一个错误/警告。
- 一个 ⋯ 溢出菜单,里面装着执行导出、推送到Google表格、导出翻译…、导入翻译…、健康检查、打开本地化报告和主题设置…。在非 Google API 来源下,推送到Google表格这一项依然可见但会被禁用,禁用原因会附在标签上;当项目里没有任何本地化表格时,那两项翻译菜单也以同样的方式处理。
侧边栏
- 一个 All 条目位于最上方——跨表搜索,详见下文。
- 然后是每张工作表及其行数、颜色圆点,以及在任何持有暂存更改的工作表上出现的 ● 标记。顶部工具栏的小标签给出的是总数,这里说明的是具体是哪些工作表。
- 工作表会按自己的
@style分组标签归入不同分区。右键点击一张工作表 ▸ Group & color ✎ 即可设置;没有标签的工作表留在默认分区。 - 工作表列表下方是一个 READ-ONLY 分组,列出插件注册的代码注册表。
- 这里同样会如实显示徽标:
parse failed出现在预览中缺失的标签页上,name clash出现在某个代码注册表与一张真实工作表同名时,以及下文描述的隔离提示。 - 每一个当前被阻止的右键菜单项都会保持可见,并附上被阻止的原因。
表格
- 一个吸顶的四行表头:来源工作表的列字母位于原始的
@name/@type/@desc单元格之上。列 A 用于存放标记,因此数据从 B 开始。 - 一个带有真实工作表行号的行号槽,以及每行一个的引用标签:两条或更多记录指向这一行时显示
shared N,恰好一条指向时显示↩ 1,没有任何记录指向时则不显示。 - 字母和行号与错误报告中打印的坐标完全相同,因此"第 5 行,C 列"可以被直接定位。点击它们会选中对应的列或行,以便进行多目标操作和拖动移动——见下文的选择行与列。
- 字母归属于座位,而不是归属于列本身。移动一列,它显示的会是反映之后它将落座的位置所对应的字母。同样的规则也让一列你已新增但还未推送的列,显示出它即将获得的那个字母。
- 结构编辑存在于右键菜单中。列表头提供属性、移动、在两侧插入以及删除;行号槽提供上移、下移和删除。被阻止的项会保持可见并附上原因。
- 列表头还提供 冻结到此列为止,它会把该列以及它左侧的所有列固定在水平滚动范围之外(见下文)。
- 列菜单其余的部分——列宽、自动调整列宽、隐藏、筛选、清除列数据以及排序项——将在下文的列宽、隐藏与按列筛选一节中说明。每个字母单元格的右侧边缘都带有一个用于调整宽度的拖动手柄。
- 在一个引用单元格内部,只有损坏的列表片段会被高亮显示。
画布
- 当你激活某一行时,会在表格下方展开。
- 你打开的那条记录位于中间:它所消耗的东西从左侧流入,消耗它的东西则位于右侧。画布上方的一个分段控件决定两侧各展开多远。
- 拖动把手可以调整大小,
Esc可以将其关闭。 - 每张节点卡片都会显示它的引用端口,以及以可编辑取值行形式呈现的普通列,因此画布是第二个可以编辑的地方,而不只是一张图(见下文的在画布上编辑)。
节点检查器
位于画布右下角。它包含:
- 该节点的单元格地址(点击可在网格中定位到该单元格);
- "共享记录" / "该键不存在" / "该记录是新建的"提示;
- Used by 列表(点击其中一项可跳转过去);
- 内置的 Go to this sheet 操作;
- 在适用时出现的 Duplicate and split / Cancel new row。
Problems
底部面板承载着与一次导入产生的诊断完全相同的内容,由同一个报告渲染器渲染。管线才是唯一的真实来源;窗口从不会自己编造消息。点击一行会聚焦到出错的单元格,并打开它的画布。
领域面板
一个右侧窗格,每个插件注册的面板占一个分段,可折叠,并会记住你上次打开的是哪一个。只有当某个插件注册了面板时,它才会被绘制——如果没有任何面板被注册,就不会有一个空盒子,因为一个空盒子等于在宣称少了什么东西。
推送弹窗
写入前的差异对比:每一处暂存更改的标签页 · 行键 · 字段 · 旧值 → 新值,以及在某些编辑被隔离时附带的说明。一个 Addressables 分区会列出这次反映将要进行的每一项资源注册(新增 · 移动 · 创建组——见编辑单元格)。取消操作不会写入任何内容。
编辑单元格
- 编辑控件跟随
@type。它读取的@type是屏幕上当前显示的那个,所以一列你已经新增或改过类型但还没有推送的列,也已经拿到了对应类型的编辑控件。- 必填的
bool是一个开关;可选的bool会打开与 enum 单元格相同的选择器,因为它有三种状态。 Enum<T>显示为它的取值加一个 ▾,点击会打开与引用单元格相同的可搜索选择器窗口。未识别的取值会停留在列表顶部,而不会被静默改写。当该 enum 是在某张工作表中定义的,选择器末尾还会带上 "Add a new member…"。空的可选单元格会显示为 —,或 —(默认)。RecordId@Tab列会得到一个引用下拉菜单(见下文)。AssetRef@Group列会得到一个资源选择器,并可以接收拖放(见下文)。Color/AnimationCurve/Gradient列会得到 Unity 自己的颜色、曲线与渐变字段(见下文)。- 其余的一切都是规范的原始文本——数字、字符串、键、非引用的
List<>、包装类型、自定义类型——因为解析器往返处理的正是这段文本。
- 必填的
- 引用单元格永远带有一个下拉菜单。
RecordId@Tab单元格是一个文本框外加一个 ▾ 按钮;手动输入键依然可行。即便目标工作表当前没有任何候选项,这个按钮也会存在:这种状态通常意味着此刻有什么地方出了问题,而这恰恰是你最需要这个工具的时候,选择器会说明情况,并提供创建选项,而不是打开一个空列表。List<RecordId@Tab>单元格会得到+▾。选择器会保持展开,每一行都是一个复选框,勾选三条记录只需要打开一次。勾选即追加、取消勾选即移除该元素,每一次勾选都是独立的一步撤销。- 元素的顺序不是下拉菜单能回答的问题。请从画布中重新排序元素,每个列表元素都有自己的 ▲▼ 行。
- 标量单元格在选中后会替换取值并关闭,单元格里已有的键会被标记出来,避免你重复选择。
- 可选列可以被重新设置为空。 当某一列声明了
?或=default时,各个选择器——引用、enum 与可选布尔皆然——都会带有一行留空选项,并标注该单元格会回落到的取值。必填列不会有这一行,因为在那里空单元格就是一个错误。 - 直接从单元格创建你缺少的那条记录。 如果你想要的键还不存在,就在选择器中按下 + Create a new … record:搜索框会变成一个预先填好该工作表公共前缀的键输入框。输入一个名字,按下 Enter,这一行就会被创建,同时作为一步
Ctrl+Z操作写入这个单元格。- 当这个操作行不通时,这一行选项不会出现。一个由代码拥有的键空间无法被添加,选择器会用一句话说明这一点。只读来源、正在运行的管线,或者一张 xlsx 来源的工作表,则会用画布使用的同一套关卡将其阻止。
- 资源单元格带有选择器,并且可以接收拖放。 一个
AssetRef@Group单元格是一个文本框外加一个 ⊙ 按钮,设计思路与 Unity 自己的对象字段一致。无论资源以哪种方式抵达,规则都是相同的。- ⊙ 会打开 SheetForge 的资源选择器:列出该组中已有的地址——当该列带有
<Type>限制时会收窄到该类型,子资源会在各自父项之后以parent[sub]的形式列出——并带有搜索功能,当前取值会被标记出来。列表下方的一行 ⊙ 浏览项目… 会打开 Unity 自己的、按该类型过滤过的对象选择器。 - 你也可以把资源从 Project 窗口拖放到该单元格上:标量列接受一个资源,
List<>列则可以接受任意数量(按顺序追加;单元格中已有的键会被跳过)。 - 一个已经在该组中注册过的资源会保留它原有的地址。一个尚不可寻址的资源会被暂存以待注册:单元格会立即获得它的地址——不带扩展名的文件名——而组条目、以及在组本身尚不存在时的这个组,都会在你反映的时候才被创建,且是在工作表写入成功之后。在那之前,项目中的任何东西都不会改变,丢弃暂存内容也不会造成任何改变。
- 一个已注册在另一个组中的资源会先征询确认——一个对话框会指出这两个组的名字,以及有多少其他单元格正通过旧的那个组引用它——然后暂存一次移动。
- 会被拒绝、并用一条 toast 提示说明原因的情形:场景对象、文件夹、把多个资源拖放到一个标量单元格上、一个不满足该列类型限制的资源,以及一个已被该组中另一个资源占用的地址。
- 暂存的注册会出现在推送弹窗的 Addressables 分区下,并计入顶部工具栏的小标签。
Ctrl+Z会把单元格取值和这项注册一并撤销;把单元格重新输入成不再有任何引用指向该地址时,也会在同一步里丢弃这项注册,因此一项过期的注册绝不会独自遗留下来。 - 每个资源单元格右侧还常驻着一个 ↗ 按钮:按下它,Project 窗口就会显示并选中该资源——列表单元格会选中它持有的每一个资源、显示第一个,而一个
parent[sub]地址会显示子对象本身。Ctrl+click(macOS 上为 Cmd+click)点击该单元格效果相同,普通点击则依然是编辑文本。当地址无法解析到资源时,这个按钮会保持可见但被禁用,原因会以工具提示的形式呈现。 - 右键点击一个单元格可以使用在项目中显示——列表单元格同样适用——以及,在可选列上,清除(默认)。画布的取值行带有相同的显示按钮,因为它们就是同一个部件。
- 在你反映之前,Problems 会报告
UnknownAssetKey和AssetTypeMismatch;而一项暂存的注册本身不是错误——投影已经把它计算在内了。没有安装 Addressables 包时,⊙ 按钮和拖放都会被禁用,原因会以工具提示的形式呈现;手动输入地址依然可行。
- ⊙ 会打开 SheetForge 的资源选择器:列出该组中已有的地址——当该列带有
- 资源单元格会展示资源本身。 当
AssetRef单元格的地址被解析成功时,文本旁边会出现一个小小的缩略图——凡是编辑器能够渲染出预览的资源类型都适用,其尺寸经过调整以确保行高永远不变;List<>单元格会显示其第一个元素的缩略图。- 点击缩略图会打开一个浮动的放大视图;在记录画布上,图片资源会在卡片上以更大的尺寸绘制。
- 一个无法解析的地址只会不显示缩略图——↗ 显示按钮已经带有相应的原因说明。
AssetRef<AudioClip>单元格可以播放。 片段地址旁边的播放按钮会通过编辑器自己的预览通道播放它;再次按下会停止播放,切换单元格、关闭窗口、领域重新加载同样也会使其停止。- 当编辑器构建版本无法提供预览功能时,按钮会保持可见但被禁用,原因会以工具提示的形式呈现。对于资源不是音频片段的单元格,则根本没有这个按钮。
- 颜色、曲线与渐变单元格就是原生字段本身。 一个
Color、AnimationCurve或Gradient标量单元格本身就是 Unity 的颜色字段、曲线字段或渐变字段——整个单元格皆是如此,没有原始文本。- 每一次更改都会提交规范文本(见表格语法)。一连串的更改——在颜色选择器中拖动、一次曲线编辑器操作会话——会合并为一步撤销,与打字遵循的是同一条规则。
- 在一个可选列上,空单元格会显示为 —。点击它会以类型默认值打开该字段,右键 ▸ **清除(默认)**可以重新将它清空。
List<Color>、List<AnimationCurve>和List<Gradient>都是纸片编辑器(chip editor):每个元素对应一个纸片(一个色块、一张曲线缩略图、一条渐变条),外加一个+纸片。点击会打开一个弹出面板,其中每个元素都带有一个原生字段,外加 ▲▼ 和 ✕;新增、移除、重新排序,以及每一次元素编辑,都各自是独立的一步撤销,因为列表的顺序也是数据。其他类型的列表仍然保持规范文本形式。- 画布上的取值行使用的是完全相同的部件。
- 从列表单中把一个资源列限制为某种类型。 在列属性表单中——以及在新增列和创建工作表的表单中——
@type字段旁边始终会有一个**类型…**按钮;只要正在输入的记法是一个AssetRef@Group,它就会启用,否则会保持禁用,原因会以工具提示的形式呈现。它会列出项目能加载的资源类型(可搜索,短名称作为标题、全名作为副标题),并把该字段重写为AssetRef@Group<Type>,同时保留List<>、?和=default不变;**不限制(任意资源)**会移除<…>。手动输入这项限制同样可行。列表头的工具提示会显示解析出的全名。 - 所输即所见,即时生效。 网格中的文本是 baseline 加上你的暂存内容,因此它从不会等待验证结果。一个已提交的取值,会在提交的瞬间就显示出它的暂存色——无论是从下拉菜单中选取的值、一次可视化取值编辑,还是快速打字,都是如此,哪怕该单元格此刻仍持有焦点。开销更大的预览部分(Problems、计数器、标签、画布)每一轮编辑才重新计算一次,而不是每敲一次键就算一次。画布上的一次性手势是例外,它会当场重新绘制。
- 输入时不做内联验证——诊断信息只来自一个渠道(预检/导入验证器),并显示在 Problems 中。
- + Row 会新增一条记录,并给出一个建议的 id(基于公共前缀检测、避免冲突)。每一次暂存的更改——单元格编辑、键编辑、新增行、全部丢弃——都是一步 Ctrl+Z / Ctrl+Y 操作。带着暂存更改关闭窗口时会提示保存/丢弃/取消。
- ↑ Push to source 会运行共享的调度流程:预检 → 按来源类型写回 → 自动重新导入。键重命名依然会询问"将更新 N 处引用——是否继续?",而 Google 推送依然会在发送任何内容之前展示计划以供确认。
- 如实的关卡:
- 只读来源(Google ExportUrl)会禁用编辑与推送,并在鼠标悬停时说明原因;
- xlsx 来源的标签页是只读的,并带有相应徽标(写回会跳过 xlsx);
- 在导入/导出/推送进行中时,拉取与推送都会被禁用。
选择行与列——以及拖动它们
网格的坐标就像电子表格中的坐标一样,是可以操作的把手。
- 点击行号可以选中该行;点击列字母可以选中该列。
- Ctrl+点击 可以把更多行/列切换进选择范围;Shift+点击 会选取从上一次点击起的整个范围。
- 表头和表体会高亮显示所有被选中的内容,键盘光标所在的单元格会画出一个跟随方向键移动的选择轮廓。
- 切换工作表会清空选择——因为那里同样的数字会指向不同的列——菜单中也带有一个清除选择项。
- 拖动一个选择区域即可移动它。 抓住一个被选中的行号(或列字母)并拖动:一条插入线会跟踪放下时的落点,放下后会把这个选择移动到那里,作为一步
Ctrl+Z操作。- 一个不连续的选择——比如第 2, 5 和 9 行——会按照你选中它们的顺序,汇集在放下的位置。
- 当排序、搜索或筛选固定了可见顺序时,行移动会因为与菜单项自我禁用相同的原因而继续被拒绝——并且在你刚开始拖动的那一刻就会说明这一点,而不是悄悄地不移动。
- 右键菜单会作用于整个选择范围。 在选中了多个列时,列宽…、自动调整列宽、隐藏、◀▶ 移动、删除以及**清除列数据…**会应用到每一个被选中的列;在选中了多行时,移动和删除会覆盖所有这些行——每一批都是一步撤销。
- 只对单个目标有意义的项目——属性、筛选、排序、冻结、插入——会单独归入它们自己的单目标区块。
- 被阻止的项目会像其他地方一样,保持可见并附上原因。
选择是一种仅存在于视图层面的手势:在某个操作真正用到它之前,不会有任何内容被暂存或写入。
菜单本身现在是同一个组件。 Studio 中的每一个上下文菜单和下拉菜单——列表头、行号槽、工具栏的 ⋯、侧边栏、画布节点与连线、单元格菜单——都拥有相同的形态:带标题的分区、勾选标记、键盘导航,以及保持原位并附带原因的禁用项。这与网页应用菜单的形态完全相同,因此两者之间不需要重新学习。
在画布上编辑
画布编辑的是与表格相同的暂存缓冲区。下文的一切都只是一次普通的暂存更改:它会显示在推送弹窗中,是一步 Ctrl+Z 操作,并通过同一套预检和重新导入链路被写回。
画面上画的是什么
一切都沿着一个方向流动:素材在左侧,使用这些素材的东西在右侧,你打开的那条记录居中。
画布上方的一个分段控件决定两侧各展开多远:
- 素材 → 本记录 → 使用方——各一步;
- 仅素材——两步,用于追踪一条组装链;
- 仅使用方。
一张自身没有引用列的工作表左侧不会有任何内容,因此它只会单独提供后者那个选项。之所以设置这个步数上限,是为了不让某一个被广泛使用的素材把整个项目都倾泻到屏幕上。如果想看得更远,双击某个相邻节点即可将其设为新的终点节点。
- 同一条记录即便被到达两次,仍然只算一个节点。
- 一条不存在的记录依然会被画出来,并标记为损坏,因为一条你看不见的连线,就是一条你无法修复的连线。
- 循环也不会被隐藏:闭合循环的那条边会沿着卡片下方的一条通道以虚线折返,让你能追踪它回到哪里。
这个布局是确定性的——相同的数据永远产生相同的画面。节点位置可以在本次会话内被拖动,而拖动的结果是刻意不保存的。
一张节点卡片上有什么
卡片头部带有键、一个副标题(它所在的工作表,或插件提供的人类可读名称)、单元格地址,以及一个统计还有多少其他记录指向它的徽标。
头部下方,引用端口始终可见。端口是连线插入的地方,隐藏任何一个都会让画面失真。每个端口都带有一个实心或空心的圆点、它接受什么,以及已经链接了多少条;列表端口会按顺序显示其元素,每个元素都带有移动和移除控件,因为列表的顺序本身就是数据。
普通列会折叠进一个"n 个值"分组,在终点节点上展开、在其他地方折叠。每一行都是一个可以输入的取值行——使用与网格相同的编辑控件,通过同一道关卡提交。端口圆点会染上它们所接受的工作表的颜色,因此一条链路读起来就是同一种颜色。
卡片展示的是与表格相同的投影。 一列在这一批次中被暂存过的列——包括尚未反映的、必填的和引用类型的列——已经出现在卡片上,并像表头一样标记为"待处理",连提示信息也一并带着:一列被暂存的引用列会显示为一个端口,一列被暂存的普通列会显示为一个取值行,一次被暂存的重命名会在原有取值上方显示新名称,一次被暂存的删除也会把这一行从卡片上移除。往一张已有数据的工作表新增一个必填列时,只要空单元格还在被填写,卡片就不会被清空——画布展示的始终是反映之后工作表将会呈现的样子,与网格完全一致。
卡片右肩处有一个单独的输出圆点。这条记录导出的就是它自己,所以只有一个。从它拖出连线所提出的问题("我在哪里使用这个?")与从端口拖出连线所提出的问题("这个指向什么?")正好相反。
只有当项目中确实存在某张工作表拥有一列接受这张工作表时,它才会被画出来,因为一个无处可去的圆点是一个注定会失败的可操作提示。这里的判断依据是架构(schema),而不是数据:一列只要声明了 RecordId@ThisSheet,哪怕还没有人写过一行数据,这个圆点也会保持存在。
手势与菜单
圆点就是操作把手。 按下端口圆点会开始手势操作,而按下该行的其他任何位置都不会,因此不会有东西被意外抓取。按下再原地松开仍然算作一次点击。
- 卡片的头部是它自己的把手:
- 点击它可以选中该卡片,这也会把它提升到与它重叠的其他卡片之上;
- 拖动它可以在本次会话中移动该卡片;
- 双击它则会把这条记录设为新的终点节点。
- 右键点击空白画布 → New record。 会打开一个级联选择器:左侧窗格列出当前已画出的端口所指向的工作表,右侧窗格承载搜索、创建和记录列表,当有不止一个端口可能接收该记录时,第三页会询问由哪个端口接收。
- 插件可以缩小或扩大这份工作表列表。插件声明了但屏幕上没有端口接受的工作表,仍会保留在列表中并附上原因,而不会直接消失。
- 这里不存在脱离上下文的"新建记录"——每一条在画布上诞生的记录,诞生时就已经是被链接的。孤立的一行要靠表格里的 + Row 来实现。
- 点击一个空的端口圆点,或者右键点击一个节点 → Connect,即可链接该列。选择器会在光标所在位置打开,使用的是与网格相同的可搜索键列表。
- 两行表头会说明这个槽位接受什么、这次选择将被写入哪个单元格。
- 每一行都带有键、其显示名称,以及已经有多少处指向它,已经在这里链接过的键会被标记出来,而不是被静默地重复添加。
- 如果你想要的记录还不存在,搜索框会变成一个填好了该工作表公共前缀的键输入框。输入一个名字,按下 Enter,它就会在一次手势中被创建并链接,一步
Ctrl+Z即可撤销整个手势。一个空的或已被占用的名字,会说明这一点(以及被谁占用),而不会创建任何东西。
- 你在画布上创建的记录,会成为新的画布中心。 视图会像双击一张卡片那样跳转到它,因此新记录会居中显示,你刚建立的链接就在它旁边。(分叉是例外——分叉的意义就在于此处的终点节点保留自己的一份副本,因此视图会留在原地不动。)
- 从一个空的端口圆点拖出连线,连线会跟随光标:松手放在一张卡片上即可链接,放在空白画布上则会在那里打开选择器。
- 从输出圆点拖出连线则相反。在一张卡片上松手,画布会找出它的哪些列能够接收这条记录——只有一个候选时直接链接,多个候选时会询问选哪个。放在空白画布上则会打开镜像的级联菜单,列出可能接收它的工作表,包括当前不在屏幕上的工作表。
- 拖拽进行中时,一切不相关的内容都会变暗,而可以接受它的端口会发光,因此合法的目标是直接可见的,而不需要靠猜。
- 每一次完成的手势都会用一条简短的 toast 提示回应,说明写入了哪个单元格——如果重要的话,还会说明这条链接闭合了一个循环,或者这条记录现在与其他人共享。
- 拿起一条已经接好的连线。 拖动一个已填充的单引用端口会把那根连线本身提起来,就像从插座里拔出一根电缆一样。放到另一张卡片上即可重新指向它,或者放到另一个端口上则会把链接移动到两个单元格之间——依然是一步撤销,且只要有一个计划不成立,两个单元格都不会被写入。放回原处,或按下
Esc,则什么都不会改变。- 放到空白画布上会在光标处打开该单元格的选择器,其中会把断开连接作为选择器内的一行提供,而不是当场执行:手滑一下绝不能就此抹掉一条链接。
- 不移动、只是点击这样一个圆点,则会改为选中这条连线,因此这两种手势永远不会互相干扰。
- 一个已填充的标量端口,仍然是别人拖拽操作的合法目标——放到它上面意味着替换。
- 列表端口没有单一的连线可以提起,因此总是会开始一条新链接。移除或重新排序某一个元素,要靠该元素自己的 ✕ / ▲▼ 行来完成。
- 连线的线身是用来选中的,不是用来拖拽的。 在连线上的任意位置点击——可点击的判定范围会跟随它路径上的每一段——即可选中它并打开连线检查器。按
Delete或右键点击 ▸ Disconnect 即可断开链接。重新指向要用上文的端口手势,因此每件事都只有一种做法。 - 右键点击一个节点 → Delete this record。 一个对话框会列出将会失去的一切:有多少条连接指向这条记录,以及该行上有多少条暂存的编辑会被丢弃。
- 分叉一条共享记录。 当一条记录被用在多个地方时,节点检查器会提供 Duplicate and split。它会把每一列都克隆到一个新键下(键名建议取自该工作表的前缀),并只把这个画布上的链接重新指向这份副本。这是一步撤销操作,其他所有人仍在使用的那条记录不受影响。
- 连线检查器会随选中的连线一起打开。它遵循*一行就是一个 token(词元)*的原则:链接所写入的单元格,以及该单元格的完整文本按 token 拆分并标出这一行对应的是哪一个。
- 当打开该边的插件对其做了描述时,会有一行用于编辑 token 中不属于键的那部分(
attack:add:10中的add:10)。编辑这一行只会重写那个剩余部分;改变它指向什么则是重新指向,属于端口手势。 - 在这里你还可以打开它所指向的记录,或者剪断这条链接。
- 当打开该边的插件对其做了描述时,会有一行用于编辑 token 中不属于键的那部分(
Delete键会读取当前选中的对象,并判断这个选择在这里意味着什么。- 选中一条连线时,它会断开这条连线。
- 选中一张卡片时,行为则取决于这张卡片是否是你打开的那条记录。在终点节点上——也就是位于中间、这个界面所围绕的那条记录——它会删除这条记录,走的是与菜单项相同的确认对话框。
- 在任何其他卡片上,它会一次性切断该卡片与这个界面之间的所有连接,因为在这里,那张卡片是素材,而不是主体。这是一步撤销操作,其中的计划是串联在一起的,所以一个列表列会失去所有匹配的元素,而不是只留下最后一个;一条无法切断的连接会说明原因,而不是悄无声息。
- (右键点击 ▸ Delete this record 无论用在哪张卡片上都始终意味着删除——快捷键的含义会跟随选择对象而变化,菜单项则是明确的那一个。)
- 插件绘制的、并非工作表行的卡片没有任何东西可删除或解除链接,因此这个键在它上面不会做任何事。
- 一条不与任何东西链接的新记录,不会出现在别人的画布上。 一条新行只有在一次暂存的连接把它与屏幕上的某个东西绑定起来时,才会出现在这里——否则,表格里一条还没完成的行就会跟着项目里的每一个画布到处出现。
- 这不会造成任何损失。从画布上创建一条记录会立即把视图跳转到它,所以你刚创建的那一行正是你正在看的那个。在表格中创建的行则留在表格里。而一条最终没有链接到任何东西的行,无论它是否曾被画出来,都会在反映对话框的丢弃列表中被列出,然后才会被丢弃。
- Ctrl/Cmd + 滚轮可以缩放画布,缩放范围在 25% 到 200% 之间,并保持光标所在的点位不动。画布头部显示的百分比同时也是一个按钮,点击即可恢复到 100%。单纯滚动滚轮依然是滚动画面。
- 按住鼠标中键——或 Alt + 左键——拖动即可平移画面。 按住时光标会发生变化,让你清楚看到的是整个视图在移动,而不是视图上的某个东西在移动。
- 单独的左键拖动仍然保留"选中并链接"的含义,这也是平移要单独占用一个按键的原因。Alt + 左键则是为没有中键的鼠标和触控板提供的等效手势。
- 平移会在内容的边缘处停下:这是一个滚动视图,不是一个无边的平面,因此你不会把整张图弄丢在空白处。
断开连接与拒绝
断开连接会在你按下之前,就说明会发生什么。 清除操作从不会被拒绝,但菜单项会把后果写清楚:
- 一个带默认值的可选列会回落到那个默认值,因此连线消失,记录在运行时依然能被解析;
- 一个没有默认值的可选列会直接变为空;
- 一个必填列会变成一个 Problems 会报告的空单元格——你可以先把它暂存下来,预检会阻止反映,直到你把它填上;
- 一个列表则只会失去那一个元素。
验证只走一条通道;画布从不会自己另外再跑一套。
有两件事确实会被拒绝而不是被假装完成,菜单会说明是哪一种:
- 一条没有说明自己写入哪个单元格的连线,无法被编辑。 对于它自己读取的引用,Core 会自动填上这个信息;而手动添加连线的插件则需要自行提供它(或者诚实地不提供)。
- 藏在自定义类型内部的一条链接——例如
Modifier取值内部的属性名——只有当打开该边的插件也选择启用了IAuthorableEdgeContributor时,才可以被编辑。否则这条连线就只能用于显示。
重复的键、只读来源、xlsx 来源的标签页,以及正在进行中的导入,都会禁用画布上的创作操作,其方式与它们禁用表格的创作操作完全一致,并且都会在菜单项中说明原因。
结构编辑
以下的一切都会像单元格编辑一样被暂存——立即可见、可撤销,并通过一次写回来确认。这些操作入口都位于上文描述的右键菜单中(列表头 · 行号槽 · 侧边栏工作表)。
Studio 还在工作表标题栏(工作表名称旁边)保留了一些常驻按钮,这样即便不知道右键菜单的存在,也能找到最常用的那些操作。其中包括 + Row 和 + Column(在末尾追加一列)。同一条工具栏上还带有工作表重命名用的 ✎、@overlap 行开关,以及搜索与排序控件。若要把新列插入到特定位置,仍然需要通过右键点击表头来完成。
- 列:原地新增、删除、移动,以及编辑属性。
- 属性表单(表头上的 properties ✎)会同时编辑名称、
@type、@desc和@overlap。只有标记单元格会发生变化;该列的数据单元格会被 100% 保留(不会出现"先删除再新增"式的数据丢失)。 @overlap是一个复选框。该行会在首次需要时自动创建,并且在键列上会被禁用,因为键列始终唯一。@type输入会随输入即时验证。在真正写入之前,预检还会验证每一个现有单元格是否与新类型兼容。
- 属性表单(表头上的 properties ✎)会同时编辑名称、
- 标记:新增/移除可选的
@overlap行。工作表自己的@style分组标签和颜色,会通过同一条路径暂存(侧边栏右键 ▸ Group & color ✎),因此分组与配色会像其他任何编辑一样被推送到工作表本身,而不是只保留在编辑器本地的状态里。 - 行:删除;用 ▲▼ 重新排序(在 Studio 中,对应行号槽菜单里的"move up" / "move down")。
- 列重排序——任意次数的移动,都在一次反映中确认。待处理(新增)的列同样可以重排序,甚至可以一路移到最前面,越过已有的列。
- 所有结构编辑过程中,注释和空白行都会被保留。
所见即所得:网格就是反映后工作表的实时预览
你暂存的一切都会立即呈现在你眼前:
- 新增的列会立即出现——你可以在同一批次中填写它的单元格(无论是已有行还是新增行)。这就是如何为一个已有数据的标签页新增一个必填列的方法:新增该列并同时填好值。未填写的必填单元格会被预检捕获。
- 被删除的列/行会立即消失。 暂存摘要会列出待处理的内容(
Deleted: column 'hp'·Added: column 'mp')——仅供展示。 - 一切都可以在同一批次中自由混合:值编辑、新增行、多次列新增/删除、标记切换和重排序——没有"每批次仅限一种操作"的限制。
- 删除一个已经有暂存编辑的列/行(或取消一个已填写的新列)会询问*"N 处编辑将会丢失——是否继续?"*——不会有任何内容被静默丢弃。
标签页重命名与 A↔B 互换——引用跟随数据
标签页重命名("Rename tab ✎")会重命名来源本身,并在一次确认对话框之后,更新所有工作表中每一处 @type 引用到该标签页的地方(RecordId@Foo → RecordId@Bar,包括列表和自定义写法)。重命名来源具体是指:本地上重命名文件并保留扩展名,Google 上则是更改标题、内容不受影响。
在一个批次内即可支持互换(A↔B)与循环重命名:先暂存哪一半都可以,引用会跟随数据走(原子化的互换重写)。
- 本地会在一次写入中交换两个文件的内容,并清理过期的旧扩展名文件。
- Google 会以拓扑顺序执行标题更改,并使用一个临时标题来避免出现任何瞬时的重复。
之后重新导入会自动完成清理工作:生成类的重命名、旧类文件的删除、烘焙 SO 与 Addressables 地址的重新注册。
键(RecordId)重命名与引用传播
直接在网格中编辑一个键单元格。在反映时,经过一次"N 处引用将被更新——是否继续?"的确认后,每个标签页中引用该键的每一个单元格(RecordId@ThisTab 标量以及列表元素)都会被一并更新。本地和 Google 两条路径都支持。边界:
- 传播只会触及 baseline 中的单元格。你在同一批次中刚刚输入的文本绝不会被静默重写;预检会捕获悬空引用,让你自己有意识地去修复它。
- 如果传播将会触及一个 xlsx 来源的标签页,整个反映都会被阻止,因为绝不允许部分反映。请直接编辑该工作簿,然后重新导入。
- 次级整数键(
IntId)也可以用同样的方式编辑。
Ctrl+Z / Ctrl+Y——接入 Unity 原生撤销
每一次暂存更改,都与 **Unity 原生的撤销(Undo)**集成在一起:
- 单元格编辑;
- 键编辑;
- 列的新增/移除/取消;
- 行的新增/删除;
- 标记切换;
- 重排序;
- 属性编辑;
- 标签页重命名;
- 画布上的链接与解除链接;
- 资源拖放,及其暂存的注册;
- 甚至"放弃编辑"。
有两个边界需要了解:
- 当你正在文本框中输入时,该文本框自身会优先消费 Ctrl+Z(这是标准的 Windows 行为)。
- 一次成功的反映之后,暂存历史会被清空——Ctrl+Z 只能在反映前的这段会话内移动。已经写入工作表的更改,需要通过编辑工作表本身来撤销。
暂存的编辑能挺过重新导入
暂存的编辑携带的是一个逻辑地址(标签页 · 行键 · 字段),而不是物理行号,并且会在反映之前被重新解析。因此你的暂存内容可以挺过自动重新导入和后台的 baseline 变化。
如果工作表在外部发生了破坏解析的更改——该行的键在外部被重命名、该行被删除,或某个键现在发生了冲突——那次编辑就会被隔离。被隔离的编辑会从本次反映中排除,并显示一个"隔离"徽标。它既不会被静默丢弃,也不会阻塞你会话的其余部分;你可以在确认后逐条丢弃它。
预检验证——先验证,再反映
写回时首先会在内存中验证整个投影后的状态——引用完整性、@overlap 唯一性、资源键与资源类型(本次会话中暂存的注册会被算作已经存在),以及任何插件领域验证器。如果验证失败,任何内容都不会被写入,你会得到完整的报告。只有当整个投影状态全部通过之后,写入才会开始;暂存的 Addressables 注册会在工作表写入成功之后、自动重新导入之前运行,而一次唯一的暂存更改只是一项注册的反映,同样会运行它并重新导入(见数据源、导出与推送)。
工作表的创建 / 删除
- 创建:从两种内置模板之一开始,也可以从一个插件注册的模板开始,或从零开始自行定义字段。一次点击即可创建本地文件或 Google 标签页(会先给出警告)。
- 两种内置模板分别是*物品示例(仅核心类型)*和 Enum definitions(用于排布一张
@enum表,见上文)。 - 插件注册的模板只有当某个插件提供了模板时才会出现——例如 Plugin Demo 的技能标签页。
- 两种内置模板分别是*物品示例(仅核心类型)*和 Enum definitions(用于排布一张
- 如果你创建到的来源,与你当前正在导入的来源不是同一个,对话框会在动手之前说明这一点。自动重新导入只会读取旧的来源,永远看不到新的标签页,因此创建操作会切换导入来源,改为你创建所使用的那一个,并把这个改动保存到设置资源中。
- 删除:会一并清理所有相关内容:来源、baseline、烘焙的 SO,以及生成的
.cs(附带强警告与确认)。
跨表搜索(All 条目)
侧边栏中的第一项是 All:输入一个词,它就会按部分匹配搜索每张工作表的 id 和字段取值,以工作表 · 键 · 字段 · 取值的形式列出结果,每页 50 行。搜索框留空时,它会浏览每张工作表中的每一条记录。
它读取的是已烘焙的数据库,因此需要先成功完成一次导入;在还没有任何一次成功导入时,它会明确说明这一点。当一次导入完成,或活动设置发生变化时,结果会自动刷新,而不会停留在一个过期的答案上。
一行结果是一扇门,而不只是一条罗列条目。双击它——或者选中它并按下 Enter——对应的工作表就会打开,并选中匹配到的那个单元格;单击只会选中这一行。由于结果来自已烘焙的数据,一条结果可能指向一张当前会话尚未加载的工作表——那一行不会跳转,列表下方会有一条简短的提示说明原因,而不是什么都不做。
打开一张导入失败的工作表(隔离)
过去,一个验证错误会让你无从下手去修复它:导入失败,窗口里就不会出现任何工作表,唯一的出路是直接打开电子表格本身。现在这一切被反转了过来。
获取与保存,与验证是分开的。 只要来源被完整读取,即便验证失败,工作表也依然会被保存为 baseline 快照——因此 Studio 会打开它们,把每一个错误对应显示在出问题的单元格上,并让你像平常一样修复并推送。
被阻止的是输出端:代码生成和烘焙不会运行,直到错误数量归零——这样"不允许部分组装"这条规则,就被保留在了它本该起作用的地方——出口处。
- 你会被明确告知,而不是自己猜。 控制台会说明工作表已被保存,以及什么被阻止了。侧边栏会带有一条
⛔ N error(s) — code generation and baking are blocked提示,点击它会跳转到第一个错误;每张工作表的错误徽标则来自你在 Problems 中已经能看到的投影诊断。一张完全无法解析的工作表会明确说明这一点,而不是显示为空。 - 推送你的修复只会询问一次。 当工作表处于隔离状态时,写回会显示一次额外的确认:已有的错误会保留,而这次编辑新引入的错误也会一并写入——验证不会阻止它。它发现的一切都会作为警告列在这次反映的报告中,随后的自动重新导入会重新验证整张工作表。在一张健康的工作表上,什么都不会改变:预检依然是一道硬性关卡。
- 出口依然关闭。 导出和推送到实时工作表在隔离期间都会被拒绝,因为两者都会把最后一次成功烘焙的取值拼接进较新的工作表——这会把刚刚被修复的那些取值又回滚回去。出于同样的原因,构建会被新鲜度检查拦下,入门窗口也会显示这一状态。
- 这个标记只会在一个地方被清除——即一次导入完整走完烘焙的那一刻。更早的任何步骤都无法清除它,因此之后的一次失败,不会留下一个假的"全部正常"的状态。
排序与过滤(仅影响显示)
Studio 提供了按工作表排序的功能(可选任意列、升序/降序、类型感知的比较方式,并按项目持久化)以及一个文本过滤功能。两者都只会改变显示顺序:行号槽依然保留真实的工作表行号,排序或过滤都不会触及暂存、反映、推送或导出。
当排序或过滤处于激活状态时,行号槽菜单中的行移动项会自我禁用并说明原因,因为此时"可见的相邻行"并不是真正的相邻行。下文描述的按列取值过滤与列隐藏功能也遵循同样的规则。
冻结列(仅影响显示)
右键点击一个列表头 ▸ 冻结到此列为止,该列以及它左侧的所有列就会移动到水平滚动范围之外、属于它们自己的窗格中——这样即使你滚动到很远的一列,键仍然保持可见。取消冻结列 会释放它们。必须至少保留一列可以滚动,因此冻结最后一列会被拒绝,并显示原因。只有一列的表格没有任何东西可以冻结。
被冻结的是从左侧数起的列数,而不是某一个具体命名的列。因此移动一列会改变到底是哪些列被固定住,这与电子表格中冻结窗格的行为完全一致。
和排序、过滤一样,这是一项视图设置,按工作表存储在按项目区分的偏好设置中。它永远不会写入工作表,因此在只读和 xlsx 来源的工作表上、以及导入正在进行时都能正常工作,并且它不会出现在任何推送或导出中。
列宽、隐藏与按列筛选(仅影响显示)
每一列——无论是在数据表还是枚举定义表上——都可以手动调整大小:拖动列字母单元格右侧边缘的手柄,双击该手柄可恢复到测量出的合适宽度,或使用列菜单中的**列宽…**输入精确数值、自动调整列宽重新测量。下限是 24 px,没有上限。宽度按工作表存储,并在工作表或编辑器重新打开时恢复;自动调整会测量每一行——不仅仅是当前可见的行——因此过滤不会导致宽度跳变。
同一个列菜单还带有电子表格常见功能集的其余部分:
- 隐藏列 / 显示隐藏列 (n)——隐藏是一项视图设置:字母依然按工作表的真实位置命名(A · C · D),表头和表体中会有一条粗边界线标出隐藏列所在的位置,工具栏上的一个小标签会统计它们的数量。最后一列可见列会拒绝被隐藏,并说明原因。隐藏列在其他所有地方依然存在——画布、验证、导出与推送看到的工作表都不会变化。
- 筛选…——一份该列取值的复选清单(空单元格对应一项**(空白)**),外加一个条件:任意列上可选包含 / 不包含 / 为空 / 不为空,数字列上还可选等于 / 不等于 / 大于 / 小于 / 大于或等于 / 小于或等于。什么都不勾选时,每个值都会通过,条件依然生效。筛选会与搜索框叠加,新增的行始终保持可见,工具栏小标签会统计已被筛选的列数,清除筛选会移除一项筛选。
- 清除列数据…——经过一次确认后,会把该列在每一行(包括被筛掉的行和暂存的新行)中的取值清空,作为一步撤销。键列会拒绝该操作——每一行的名字就存放在那里,请在单元格中重命名——必填列会如实报告错误,直到重新填入取值为止。一个没有内容可清除的列不会暂存任何东西。
- 升序排序 / 降序排序 / 恢复工作表顺序——按工作表排序功能现在也出现在列菜单中,并在当前生效的选项上带有一个勾选标记。
和排序、冻结列一样,这一切都仅影响显示:都是按工作表存储、绝不会写入工作表、推送或导出的视图设置。
枚举定义表
一张定义枚举的工作表(见表格语法)没有记录,因此 Studio 会为它提供一个专属网格,而不是记录表格。这个网格会显示一列对应一个枚举,其成员按顺序列出,侧边栏中会带有一个 Enum definitions 徽标,并显示它持有多少个枚举。它读起来就像其他任何一张工作表:顶部是列字母,行号槽里是真实的工作表行号,同样顺序排列的同一套右键菜单,以及用数据表所用的同一套颜色标记出的暂存更改。
工作表的结构会像数据表一样原地创作:
- 新增一个枚举:使用表头工具栏的 + Enum 按钮(这是在一张还没有任何枚举的定义表上新增第一个枚举的唯一方式),或者从某个列表头的右键菜单中选择一个位置新增。表单会要求填写名称、可选的基础类型与说明,以及最初的若干个成员——至少一个,因为一个没有成员的枚举无法被导入。成员的顺序就是它们的整数取值。
- 重命名一个枚举,所有工作表中引用它的每一个
@type单元格都会在同一批次内被重写,因此写入之后的重新导入依然能够解析成功。原地编辑基础类型与说明——即便工作表尚未拥有这些标记行,表单也会照常显示它们,并在更改落地时创建这些行。 - 删除一个枚举——只要还有任何工作表在使用它,就会被拒绝,并点名正在使用它的那些列。自由重排枚举列;一个枚举的列位置不承载任何意义,因此这项操作永远是安全的。
- 一切都像其他任何编辑一样被暂存:立即可见、每个手势一步
Ctrl+Z、由一次反映写入。每一项判定——名称是否合法或已被占用、成员是否有效、基础类型是否被允许、这个枚举是否仍在使用——都由验证导入的那同一套代码做出,因此表单与重新导入不可能产生分歧。一个被阻止的操作会留在菜单里并附上原因,而不是直接消失。
成员行依然只能追加,且没有排序功能,因为一个成员的位置就是它的取值——重新排列成员会悄悄改写已经烘焙进资源里的数值。
单元格会精确显示工作表本身所写的内容:用 Name=value 语法固定的成员会按原样显示。重复检查只比较名称部分,因此如果一张工作表已经持有 Rare=10,再暂存一个 Rare 会被拒绝,而不是造成重复。
要添加一个成员,你甚至都不需要打开这张工作表。项目中任何位置的 Enum<T> 单元格下拉菜单,底部都带有 "Add a new member…":输入名字,它就会作为一步 Ctrl+Z 操作被暂存到枚举定义表上,并标记为"待暂存",直到下一次反映把它写入为止。
对于一个由插件从 C# 代码注册的枚举,这一行会直接不存在——而不是存在但会失败——因为该工作表并不拥有那个枚举。
Web 应用以同样的方式、遵循同样的规则来创作这些工作表——见SheetForge Web。
从控制台错误跳转到对应单元格
当一次导入或反映发现错误时,人类可读的控制台报告会在每个错误的坐标旁附加一个可点击的**"在 Data Studio 中打开"**链接。点击它会打开 Studio、切换到对应标签页,并高亮该单元格(行左侧一道竖条,单元格带边框)。没有具体单元格的错误(文件/标签页级别)只会聚焦到对应标签页。
这个链接只会加入人类可读的报告中;供 CI 和日志抓取依赖的机器可读坐标行保持不变。
健康检查
Studio 工具栏中的 ⋯ ▸ 健康检查 会运行一次快速、无需联网的诊断。它会针对以下各项打印 ✓/✗ 及建议的修复方法:
- 活动设置;
- 来源可达性——本地文件夹是否存在,或 Google id + 服务账号密钥路径是否有效;
- 导入 baseline;
- 生成代码/烘焙结果/addressable 的新鲜度。
一个汇总对话框会告诉你有多少项检查需要处理。
活动的导入设置
当项目中存在不止一个 SheetForgeSettings 资源时,工具栏会显示一个下拉菜单,用于选择哪一个是活动资源。选中一个会立即激活它并重建视图;菜单、导入操作以及窗口都会跟随这个活动选择。如果只有一个设置资源,下拉菜单会被隐藏。
活动选择会按项目、按用户存储,因此不会触及版本控制。你也可以从入门窗口(Tools ▸ SheetForge ▸ 入门)来管理它,或者从某个设置资源的面板中管理,面板上会显示一个**"活动"徽标,或一个"设为活动"**按钮。
安全防护
- 针对本地来源的外部更改检测。
- 存在暂存更改时的关闭警告。
- 防止在过期网格上进行操作的暂存代次锚点。
- 模式感知:对于只读来源(Google ExportUrl),推送 / 反映 / 结构编辑 / 删除都会被禁用,并附带鼠标悬停说明。
- 导入/导出/推送过程中的进度条,始终会被清理(
try/finally),并已本地化。 - 一个行为异常的扩展无法拖垮整个窗口:画布覆盖、部件和操作都在 try/catch 内部被调用,出错时只会产生一条英文的控制台警告,窗口的其余部分仍会照常工作。
重命名之前需要了解的事项(反映之后不可撤销)
- 列重命名 /
@type更改会重新生成对应的生成字段(名称/类型),因此引用该字段的游戏代码必须手动更新。确认对话框会明确说明这一点,由此产生的编译中断会被自动链以一条可执行的提示语句安全中止。列的取值会被保留。 - 标签页重命名会更改生成的类名(
FooDatabase→BarDatabase)——规则相同。 - 互换与循环重命名遵循与单个重命名相同的规则(见上文的标签页重命名小节)。只有真正的冲突——两个重命名指向同一个名称——才会被拒绝。
- xlsx 来源的标签页被排除在重命名之外。表单会说明原因,并禁用 Apply;请直接在工作簿中重命名该工作表,然后重新导入。
- 在 Google 上,还遗留一处边界情况:两个互换的标签页如果互相引用,则不会被重新指向(本地路径是完全正确的)——见功能与限制。
- 反映之后,这些操作就无法通过 Ctrl+Z 撤销了(工作表已经被写入)。
测试编辑(临时调整 SO)
烘焙出的 SO 面板带有一个**"测试编辑"开关**(默认关闭 = 只读)。打开它即可临时调整 SO 的取值,尝试运行时数值——永远不会写回工作表,下一次重新导入后就会消失。记录可以在编辑器中和 Play 模式下按 codeName/id 快速查找。
工作台原本单独提供的"预览我的暂存取值到 SO 上"按钮,随着那个窗口一起被移除了。它当年驱动的那个叠加层,依然作为公共 API 保留给需要它的工具使用:EphemeralSoApply 会应用一切它能如实计算出的内容,并拒绝应用待处理的列和解析失败的单元格,而不是伪造它们。上面的开关覆盖了日常使用场景。
有插件和没有插件
凡是列在无插件(仅核心)下的内容,在一个不含任何插件的普通项目里都能正常工作。每一条有插件时的内容,则是一个领域插件所新增的东西。它们全部都在内置的 Plugin Demo 中得到了演练,因此在你动手编写自己的插件之前,可以先看到每一项实际运行的样子(见插件开发)。
- 工作表、单元格、行
- 无插件:完整表格、单元格编辑、新增行、暂存、Ctrl+Z、推送。
- 有插件时:不变。
- Pull / Push
- 无插件:从活动来源导入;通过同一套预检 + 重新导入链路推送。
- 有插件时:不变。
- Problems
- 无插件:四项核心验证(键、引用、
@overlap、资源键)。 - 有插件时:再加上你自己的
IDomainValidator规则。示例插件会对未加制动的反应循环和孤立记录发出警告。
- 无插件:四项核心验证(键、引用、
- 画布上显示什么
- 无插件:你打开的记录、它由什么构成,以及什么在使用它,以确定性的方式布局。
- 有插件时:再加上你通过
ISheetForgeGraphPlugin提供的按标签页覆盖——不是工作表记录的身份、Core 看不见的链接、按领域顺序固定的列(绝对位置,或从屏幕上的记录开始计数),以及一条记录对外呈现的人类可读名称。示例插件会在一个ExampleActions记录周围生长出事件节点和一个代码块,固定住一个ExampleSkills记录的施法阶段,并把fireball在卡片和选择器中都显示为 Fireball。
- 画出的边
- 无插件:Core 扫描器能看到的每一处
RecordId@Tab引用(标量、列表元素、默认值、包装类型内部)。 - 有插件时:再加上由
IEdgeContributor声明的边,以及画布覆盖所揭示的任何额外的边。示例插件会打开藏在Modifier迷你语法取值内部的属性引用。
- 无插件:Core 扫描器能看到的每一处
- 在画布上编辑
- 无插件:每一列都支持创建、连接、断开、重新指向、分叉、删除以及内联取值编辑;新记录可以在已画出的端口所指向的工作表中创建。
- 有插件时:再加上用
IAuthorableGraphShape决定新记录可以在哪里创建、用IAuthorableEdgeContributor让贡献者自己的边可以被编辑,以及用IEdgeTokenEditor暴露 token 中不属于键的那部分。示例插件的贡献者会在你链接或解除链接一个属性时重写modifier迷你语法,并在连线检查器中把它的op:value作为一行可编辑内容提供出来。
- 单元格部件
- 无插件:内置分支(开关、选项选择器、引用选择器、带拖放的资源选择器、颜色 / 曲线 / 渐变字段、这三种类型的列表所用的纸片列表、原始文本)。
- 有插件时:再加上你为某一个具名单元格类型提供的
IStudioCellEditorProvider。如果完全没有编写部件代码,StudioCellEditorHint可以为该类型指定七种内置形态之一(下拉菜单、多行文本、滑杆、开关、颜色、曲线、渐变)。已注册的部件优先;hint 优先于核心默认形态——当一个插件包在同一个类型名下注册了 hint 时,也同样优先于内置的颜色 / 曲线 / 渐变 hint。
- 菜单与面板
- 无插件:仅内置项。
- 有插件时:再加上你通过
ISheetForgeStudioPlugin注册的内容——检查器末尾的动作项、行菜单、列表头菜单、画布节点菜单和顶部工具栏的 ⋯、一个右侧摘要面板,以及列表头旁的徽标。示例插件会在某一行上暂存一个反应制动器、在一步撤销中填满整列,并用一个施法时间量表来汇总一个技能的组装情况。
- 富面板
- 无插件:没有任何东西。
- 有插件时:
IStudioPanelProvider可以绘制任意的 UIToolkit 面板。如果它注册的 id 与某个已描述面板相同,这里会优先使用它,而浏览器端仍会绘制那个已描述的面板。
- 侧边栏
- 无插件:仅你自己的工作表。
- 有插件时:再加上锁定的、
_Refs风格的代码注册表(ISheetForgeCodeRegistryPlugin),以只读的键/标签/raises 网格形式显示;指向这些键的边不会被画成损坏状态。
- 画布上方
- 无插件:没有任何东西(核心不附带任何部件)。
- 有插件时:你自己的
IStudioGraphWidget。示例插件会显示一条固定的阶段条(VALIDATE → CAST → COMMIT → DELIVER → APPLY),其内容取自终点节点所在的行。
- 节点检查器
- 无插件:地址、被引用列表、"Go to this sheet"、"Duplicate and split"。
- 有插件时:再加上你自己的
IStudioInspectorAction按钮。示例插件会在一个未加制动的反应上暂存brakeSeconds = 0.25(一次正常的、可撤销的暂存编辑)。
- 颜色与标签
- 无插件:内置的预设,加上每张工作表自己的
@style颜色。 - 有插件时:再加上你自己的
ISheetForgeThemePlugin预设和ISheetForgeStringsPlugin字符串——它们注册在 Core 中,因此同一个包的标签同样会出现在浏览器端。
- 无插件:内置的预设,加上每张工作表自己的
空项目的入门体验
在没有活动导入设置的情况下打开,Studio 会显示一个 "开始使用" 面板来代替表格——内含用于创建设置资源、导入 Plugin/Core 演示,或打开入门窗口的内联按钮。一旦存在设置资源,这个面板就会立即消失。
更快的方式:把一个文件夹拖到窗口上,或拖一个单独的 .tsv/.csv/.xlsx 文件(会使用它所在的父文件夹)。经过一次确认后,这会创建一个从该文件夹读取数据的导入设置资源,并将其设为活动。如果你已经有活动设置,对话框会说明这一点,并提供创建新设置并切换的选项。
工作台发生了什么
最初的 IMGUI 工作台窗口已被移除。它原本共享 Studio 的创作会话、组装/验证引擎和反映路径,因此没有任何行为被真正丢失——它独有的三样东西也已提前迁移:
| 工作台功能 | 现在的去处 |
|---|---|
| All 标签页——支持分页的跨表搜索 | Studio 侧边栏顶部的 All 条目(相同的搜索方式、相同的分页大小) |
| 拖放式入门引导 | 由 Studio 本身接收拖放(见上文) |
| Google 的 gid 自动填充 / 实时标签页列表面板 | 设置资源面板中的 Google Sheets 部分 |
有一项能力是被直接舍弃、而不是被迁移的:工作台用于把暂存取值预览到烘焙 SO 上的那个按钮。SO 面板的测试编辑开关覆盖了同样的需求(见上文的测试编辑)。
如果你有代码或笔记指向它:没有菜单项需要更新——它本来就没有菜单项——而设置面板、烘焙 SO 面板,以及入门窗口的模板画廊,现在打开的都是 Data Studio。