跳转到内容

文本打印机 ​

文本打印机是用于呈现可以随时间逐步显示(打印)的文本消息的 Actor。

可以使用 Naninovel -> Configuration -> Text Printers 编辑器菜单配置打印机的行为;有关可用选项,请参阅 配置指南。可以使用 Naninovel -> Resources -> Text Printers 编辑器菜单访问打印机的资源管理器。

在剧本脚本中,文本打印机主要通过 @print 和 @printer 命令控制:

nani
; 将使“Dialogue”打印机成为默认打印机
@printer Dialogue

; 将使“Fullscreen”打印机成为默认打印机
@printer Fullscreen

; 将使用默认打印机打印该短语
@print text:"天地玄黄,宇宙洪荒。"

; 与上面相同,但使用通用文本行
天地玄黄,宇宙洪荒。

; 与上面相同,但与角色“Felix”关联
Felix: 天地玄黄,宇宙洪荒。

请注意,即使内置打印机是作为 UI 实现的,它们仍然是 Actor,并且所有与 Actor 相关的可见性更改(显示/隐藏动画)都使用相应命令或 Actor 配置中设置的持续时间;例如,@showPrinter 命令的 time 参数控制显示动画的持续时间,如果未指定,则使用打印机 Actor 配置属性 Change Visibility Duration 作为默认持续时间;在这种情况下,打印机 UI 预制件根对象上的 Fade Time 属性会被忽略。

自动播放 ​

自动播放功能允许脚本在遇到等待输入(单击继续)事件时自动继续执行。

cover

等待输入命令(即 [-] 命令)会暂停脚本执行,直到玩家激活 Continue 输入;它们通常用于打印文本消息之后。在自动播放模式下,[-] 命令将改为暂停脚本执行一段时间,然后完成,从而允许执行下一个命令。暂停时长取决于最后打印的文本消息的长度,并受“Auto delay”游戏设置进一步调整。

可以使用 AutoPlay 输入(默认为 A 键)或控制面板中的“AUTO”按钮切换自动播放模式。

文本跳过 ​

文本跳过功能允许快进执行 @print 命令,实际上就是跳过文本显示(打印)过程。

cover

可以通过按住 Skip 输入(默认为 Ctrl 键)来启用跳过模式,也可以使用 ToggleSkip 输入(默认为 Tab 键)或控制面板中的“SKIP”按钮切换跳过模式。

默认情况下,跳过模式仅在执行过去已经执行过的命令时可用;例如,如果玩家尚未阅读将要打印的文本,则跳过模式将不可用。这可以在游戏设置中使用“Skip mode”设置进行更改。

打印机历史记录 ​

打印机历史记录是一项功能,允许玩家重新阅读以前打印的文本、查看已选择的选项、重播配音行以及(可选)回滚到已记录的消息。

cover

可以通过激活 ShowBacklog 输入(默认为 L 键)或按控制面板中的“LOG”按钮在主游戏循环期间随时显示历史记录。

可以通过附加到预制件根对象的组件自定义历史记录 UI 的各种属性;有关每个属性控制内容的详细信息,请参阅属性的工具提示。

cover

有关如何自定义和配置 UI 的更多信息,请参阅 内置 UI 自定义指南。

可以通过在打印机 Actor 配置中禁用 Add To Backlog 属性来防止特定文本打印机将消息添加到历史记录中。

cover

消息模板 ​

消息模板可以自动对文本消息进行附加处理。每个文本打印机的处理方式都可以单独配置:在运行时使用 @format 命令,或在编辑器中设置打印机面板 UI 的 Default Templates 属性。例如,下面是内置 Fullscreen 打印机的默认格式模板:

cover

您可以指定任何文本格式标签或字符,其中 %TEXT% 会被替换为消息文本,%AUTHOR% 会被替换为作者显示名称。例如,考虑以下模板:“%TEXT%” — <i>%AUTHOR%</i>——它将打印的消息用引号括起来,后面跟着一个破折号和斜体的作者名称;例如,使用此模板处理 Kohaku: 天地玄黄,宇宙洪荒。 的结果如下:

cover

分配的模板按顺序应用,Author 属性允许根据打印消息的作者过滤应用的模板。指定作者(角色 Actor)ID 以使模板仅适用于该特定作者,指定 + 以使其适用于任何有作者的消息,指定 - 以使其适用于无作者的消息,或指定 * 以将其应用于任何消息。

Dialogue 打印机 ​

Dialogue 打印机在高度可变的窗口内呈现文本。它们最初占据屏幕大小的三分之一左右,并在内容需要更多空间时增加高度。Dialogue 打印机还在文本窗口上方的标签中显示关联的角色名称。

Dialogue Printercover

Wide 打印机 ​

Wide 打印机与 Dialogue 打印机非常相似,只是面板布局针对宽显示屏进行了一些更改。Wide 打印机还支持 角色头像 功能。

Wide Printercover

Fullscreen 打印机 ​

Fullscreen 打印机在具有固定大小的窗口内呈现文本。它们占据屏幕的大部分区域,旨在呈现大量文本,也称为“NVL”模式。

Fullscreen Printercover

默认情况下,Fullscreen 打印机不会在每个后续打印命令时重置文本;请在需要时使用 @resetText 命令清除打印机的内容。可以通过在打印机 Actor 配置菜单中启用 Auto Reset 来更改此行为。

默认情况下,由 Fullscreen 打印机处理的每个打印命令都会在打印的文本之前添加两个换行符(除非打印机的当前内容为空)。可以通过在打印机预制件的 Revealable Text Printer Panel 组件上将 Auto Line Breaks 设置为零来禁用此功能。

cover

下面是使用 Fullscreen 打印机的示例。

nani
; 激活 Fullscreen 打印机。
@printer Fullscreen

; 以下行将打印在同一窗口中,由 2 个换行符分隔。
天地玄黄,宇宙洪荒。日月盈昃,辰宿列张。
寒来暑往,秋收冬藏。闰余成岁,律吕调阳。
云腾致雨,露结为霜。金生丽水,玉出昆冈。

; 清除打印机的内容。
@resetText

; 打印更多行。
剑号巨阙,珠称夜光。果珍李柰,菜重芥姜。
...

Chat 打印机 ​

Chat 打印机在窗口中以消息气泡形式呈现文本,内容可垂直滚动,类似于移动通讯应用。它不逐个字符地显示打印的消息,而是在显示效果期间显示“作者正在输入”动画,然后立即显示打印的消息。Chat 打印机支持 角色头像 功能。

Chat Printercover

要在 Chat 打印机内嵌入选项,请参阅 ChatReply 选项处理程序。您还可以通过 Chat Printer Panel 组件上的 Choice Handler Id 属性指定自定义处理程序。

Bubble 打印机 ​

Bubble 打印机可用于漫画/连环画风格的文本呈现,也称为“对话气泡”。

cover

内置的 Bubble 打印机支持两种外观:“Left”和“Right”,可用于根据打印机位于角色的哪一侧来调整其朝向。

nani
@printer Bubble.Left pos:42,80 !visible time:0
@show Bubble
Misaki: 天地玄黄,宇宙洪荒!
@char Nanikun.Happy
@printer Bubble.Right pos:53,55 !visible time:0
@show Bubble
Nanikun: Integer nec maximus elit, eget posuere risus.

要同时显示多个 Bubble(或任何其他)打印机,请添加自定义打印机。

气泡锚点 ​

大量使用 Bubble 打印机时,每次都手动指定其位置可能会很繁琐。可以改用 Actor 锚点,让 Naninovel 自动将气泡与其各自的角色对齐。

要启用此功能,请在 角色 Actor 内指定锚点位置。您有两个选择:

  1. 在角色元数据中,使用 Anchors 列表并添加一条记录,指定 Bubble ID 以及在 Actor 游戏对象内的本地位置。
  2. 如果角色是预制件(例如,分层、通用或 Live2D),请在预制件内创建一个空游戏对象,附加 Actor Anchor 组件并将 Bubble 分配为锚点 ID。

正确配置后,Naninovel 不仅会将打印机定位到锚点处,还会在打印机即将超出屏幕时将其翻转。您可以为每个角色指定多个锚点,以便根据打印机是否翻转进行更精确的对齐。以下是支持的锚点 ID:

锚点 ID描述
Bubble当没有其他锚点适合时的默认或回退锚点。
Bubble/TopLeft当气泡在左上角对齐时使用。
Bubble/Top当气泡在顶部边缘对齐时使用。
Bubble/TopRight当气泡在右上角对齐时使用。
Bubble/Left当气泡在左边缘对齐时使用。
Bubble/Right当气泡在右边缘对齐时使用。
Bubble/BottomLeft当气泡在左下角对齐时使用。
Bubble/Bottom当气泡在底部边缘对齐时使用。
Bubble/BottomRight当气泡在右下角对齐时使用。

您不必全部指定:即使缺少精确匹配,Naninovel 也会选择最合适的那个。例如,如果左上对齐但缺少 Bubble/TopLeft,它将检查 Bubble/Left,然后检查 Bubble/Top,最后回退到 Bubble。

下面是一个指定四个锚点的示例——每个角落一个:

cover

示例

在我们的 示例项目 中的 Content/Characters 下查看 Hiyori 和 Senko Live2D 角色,了解通过角色元数据和预制件内部设置气泡锚点的示例。

构建自定义 Bubble 打印机时,可以在 Floating Printer 属性下配置翻转和对齐行为。有关每个属性如何影响行为的更多信息,请参阅工具提示。

cover

使用带锚点的自动对齐时,有时您可能希望手动定位气泡。您可以使用 @printer 命令来执行此操作——当命令指定显式位置时,自动对齐将暂时禁用。要重新启用它,请使用 anchor! 标志:

nani
; 禁用自动对齐并手动定位气泡
@printer Bubble pos:50,50
...
; 重新启用自动对齐
@printer Bubble anchor!

添加自定义打印机 ​

您可以基于内置模板添加自定义文本打印机,也可以从头开始创建新打印机。例如,让我们自定义内置的 Dialogue 模板。

使用 Create -> Naninovel -> Text Printer -> Dialogue 资产上下文菜单在 Naninovel 包之外的某处创建 Dialogue 预制件,例如,在 Assets/TextPrinters 文件夹中。

编辑预制件:更改字体、纹理、添加动画等。有关可用 UI 构建工具的更多信息,请参阅 uGUI 的 Unity 文档 ↗。在 UI 自定义指南 中还有一些关于使用 uGUI 的教程视频和示例项目。

通过 Naninovel -> Resources -> Text Printers 编辑器菜单打开打印机管理器 GUI,将预制件添加到引擎资源中。使用 +(加号)按钮添加新记录,输入 Actor ID(可以与预制件名称不同),然后双击记录以打开 Actor 设置。将打印机预制件拖放到 Resource 字段。

cover

您现在可以通过 @printer 命令激活新文本打印机并指定您在管理器中设置的 Actor ID 来使用它。

nani
@printer MyNewPrinter

示例

查看我们的 示例项目 以获取有关添加自定义打印机的示例。预制件存储为 Content/Printers/Demo/Prefabs/DemoPrinter.prefab。

也可以通过手动实现 ITextPrinterActor 接口从头开始创建打印机。有关更多信息,请参阅 自定义 Actor 实现 指南。

文本显示效果 ​

打印文本消息的显示进度由 Revealable Text 组件维护,该组件包装了 Unity 的 TMPro Text 并支持所有相同的功能。为此,使用了独立组件,例如 Reveal Clipper,它根据当前的显示进度限制最大可见字符数。大多数内置打印机还应用了 Reveal Fader 组件,该组件为显示的字符添加渐变的不透明度淡入效果。

cover

要更改显示效果强度(渐变延伸多远),请更改 Length 属性。

当 Slack Opacity 小于 1 时,最后一次追加之前打印的文本的不透明度将在 Slack Duration 秒内渐变到指定值(这在内置 Fullscreen 打印机中默认启用)。

cover

当文本打印机具有固定尺寸并且无法适应不同的消息长度或字体大小时,请将 TMPro 的文本溢出模式设置为“page”并添加 Reveal Paginator 组件,该组件会将当前显示的页面与显示进度同步。可以在内置 Fullscreen 打印机中找到示例设置。

文本样式 ​

可以通过放置在文本内的富文本标签或使用 @format 命令应用各种文本样式:

nani
; 以粗体打印“天地”,以蓝色和斜体打印“宇宙”。
Kohaku: <b>天地</b>玄黄,<color=#0000FF><i>宇宙</i></color>洪荒。

有关可用标签,请参阅 TMPro 富文本文档 ↗。

提示

如果您想对以特定角色为作者或由特定打印机打印的所有消息应用特定的文本格式或样式,请查看 消息模板 功能。

注音(Furigana) ​

Naninovel 的 Naninovel TMPro Text 组件(Revealable Text 基于它)通过自定义 <ruby> 标签提供对 注音 ↗ 字符的支持。用注音标签包裹需要在上方添加注音的文本,并在标签内指定注音内容,例如:

nani
天地<ruby="xuán">玄</ruby>黄,宇宙洪荒。

— 在运行时打印消息时,“xuán”注音文本将出现在“玄”字的正上方。

cover

注意

将 <ruby> 与其他标签组合使用时,请先指定注音标签,以避免格式问题,例如:

nani
天地<ruby="xuán"><tip="TipID">玄</tip></ruby>黄,宇宙洪荒。

您可以通过更改打印机预制件中使用的 Naninovel TMPro Text 组件的属性来额外控制注音文本的大小和垂直行偏移。

Ruby Size Scale 设置注音文本相对于正文的字体大小比例,Ruby Vertical Offset 设置注音文本的垂直行偏移(支持的单位为 em、px 和 %)。Revealable Text 组件还提供 Reveal Ruby Instantly 属性(默认启用),它会使注音文本立即显示,而不是逐个字符地显示。

cover

以下是注音标签的视频演示。

cover

从右到左(阿拉伯语)文本 ​

可以在所有内置打印机中启用对 RTL 文本显示效果的支持。

cover

要在打印机中使用 RTL 文本,请执行以下操作:

  1. 从任何内置模板创建自定义文本打印机。
  2. 设置打印机内部 Revealable Text 组件中的 Enable RTL Editor 属性。
  3. 在同一组件上(在“Naninovel Settings”下拉菜单下)启用 Fix Arabic Text 属性。
cover

不要忘记使用 兼容的字体 ↗ 和图集配置;这是一个示例:

Font Size: Auto Sizing
Font padding: 5
Packing Method: Optimum
Atlas res: 1024x1024
Character Set: Unicode Range (Hex) with this Sequence:
20-7E,600-603,60B-615,61B,61E-61F,621-63A,640-65E,660-6DC,6DF-6E8,6EA-6FF,750-76D,FB50-FBB1,FBD3-FBE9,FBFC-FBFF,FC5E-FC62,FD3E-FD3F,FDF2,FDFC,FE80-FEFC
Font Render Mode: Distance Field 16

示例

有关设置支持从右到左(阿拉伯语)文本的自定义 TMPro 打印机的完整示例,请参阅 RTL 示例。

注意

Unity 原生不支持阿拉伯语文本。对于需要支持阿拉伯语的文本标签(打印机除外),请考虑使用 Naninovel TMPro Text 组件。

CJK 语言 ​

中文、日语和韩语包含大量不同的字符,而游戏中通常只需要其中一小部分。为了优化生成的字体图集大小,TMPro 有一个选项可以指定为其构建 SDF 纹理的字符集。

cover

要查找 Naninovel 将显示哪些字符,请使用可通过 Naninovel -> Tools -> Character Extractor 编辑器菜单访问的 Character Extractor 实用程序。

cover

该工具将检查指定文件夹(包括所有子文件夹)中的剧本脚本和管理文本文档,因此您将获得 Naninovel 向玩家显示的所有文本的字符,包括所有打印的文本、UI 标签、可解锁提示等。

示例

查看 本地化示例,了解如何为日语语言环境使用自定义 TMPro 字体图集。选择日语时字体会自动切换,选择其他语言时会切换回默认图集。

文本显示声音 ​

对于支持显示效果的内置打印机(除 Chat 之外的所有打印机),您可以选择设置显示字符时播放的 SFX。

按照上面的“添加自定义打印机”指南创建基于任何内置打印机的自定义打印机,然后找到附加到预制件根对象的 Revealable Text Printer Panel 组件(Bubble 打印机中为 Floating Text Printer Panel),并使用 Chars Sfx 属性设置显示字符时要播放的 SFX。可用选项的实际列表基于您通过 Naninovel -> Configuration -> Audio 编辑器菜单中的“Manage SFX Resources”按钮添加的 SFX 资源。

下图表示一种设置,其中“Keystroke1”SFX 将用于所有字符(其 Characters 字段留空),“Keystroke2”用于字符 .、,、! 和 ?,“Explosion”用于字符 *。当一个字符匹配多个元素时,将播放它们的所有 SFX。

cover

或者,您可以在角色配置中设置 Message Sound,以便在显示该角色为消息作者的文本时播放特定于角色的声音(无论哪个文本打印机正在打印消息)。

文本显示声音播放非常频繁(取决于消息显示速度),并且在连续播放相同声音时会被截断,因此请确保相应的音频剪辑非常短促(开头没有任何停顿或静音)。

如果显示声音不适合您(例如,声音不够短,无法在每个字符显示时播放),请考虑使用 ITextPrinterManager 引擎服务 的 OnPrintStarted 和 OnPrintFinished 事件来相应地开始/停止循环播放声音。

显示事件 ​

您可以监听特定字符显示时触发的事件,以执行任意操作。使用 <@...> 标签在打印的文本中指定应触发事件的位置。例如,要在显示“宇宙”后触发带有“foo”有效负载的显示事件:

nani
天地玄黄,宇宙<@foo>洪荒。

使用附加到打印机预制件的可显示文本对象的 Reveal Broadcaster 组件来监听事件。所有内置打印机均已附加该组件,因此您只需连接监听器即可。

cover

内置打印机还启用了 Play Command 选项。这将使组件尝试将事件主体(@ 之后的部分)作为命令解析并执行。例如,以下内容将在显示“宇宙”时为背景设置色调:

nani
天地玄黄,宇宙<@back tint:blue>洪荒。

您可以使用事件标签代替 内联命令 将它们公开给 本地化文档,允许翻译人员根据所选语言环境覆盖执行的命令。

注意

显示事件会在临时轨道上执行命令,且无法影响主轨道,因此无法等待它们(wait! 标志会被忽略),也无法触发“等待输入”(CTC)。

显示表达式 ​

在某些情况下,可能需要在生成的本地化文档中包含 剧本表达式 或在语言(语言环境)更改时强制对表达式重新求值。

该过程类似于 显示事件,但使用 : 标签代替 @:

nani
天地玄黄,<:random(text1, text2)>宇宙洪荒。

— 每次将文本分配给打印机时(包括语言更改时),都会对 random(text1, text2) 表达式重新求值,从而使 text1 和 text2 脚本文本变量 与当前活动语言环境同步。表达式也将包含在本地化文档中,允许为每种特定语言更改它。

显示表达式对于允许翻译人员更改注入值的顺序也很有用,因为不同语言对各种词性的顺序/优先级通常有不同的规则:

nani
Hello, <:MC>! How's <:AC> doing?

— 在这里,MC 和 AC 变量(可能包含玩家指定的角色名称)都将公开在生成的本地化文档中,以便翻译人员在必要时能够更改它们的顺序。

警告

避免在改变或依赖游戏状态的表达式中使用此功能,因为它可能会导致未定义的行为。例如,考虑一个表达式,其结果取决于局部变量 foo,而包含此表达式的消息在某个时刻被打印并保留在历史记录中。如果玩家更改语言环境,表达式将使用更改语言环境时 foo 的当前值重新求值,这可能与最初打印时不同。

选择标签 ​

显示表达式 的一个常见用例是将它们用作选择器。例如,您可能希望包含池中的随机文本或取决于玩家选择的内容,例如依赖于代词的措辞。

如果这在您的剧本中很普遍,那么每次重复完整的表达式语法可能会变得繁琐。在这种情况下,请考虑使用选择标签:

nani
; 选择一种随机颜色。
My favorite color is </red/blue/green>.

; 基于玩家选择进行选择。
Select your pronouns.
@choice "He/Him" set:selector=0
@choice "She/Her" set:selector=1
@choice "They/Them" set:selector=2
...
</He/She/They> </was/was/were> magnificent.

注意 </x/y> 标签——这些是选择标签。/ 字符之间的文本部分称为选项。默认情况下,将返回随机选项。但是,如果您将 selector 变量设置为索引,标签将改为返回具有该索引(从零开始)的选项。

如果您需要更灵活的选择逻辑,请创建一个带有 select 别名的自定义 表达式查询,并使其接受 params string[] 并返回 string。此后每当编译选择标签时,都会使用您的查询来计算结果。下面是自定义选择查询的示例,其中第一个选项指定选择类型,如果第一个选项为空,则回退到随机选择:

cs
[ExpressionQuery("select")]
public static string Select (params string[] args)
{
    var kind = args[0];
    var options = args[1..];
    return kind switch {
        "p" => SelectPronoun(options),
        "t" => SelectTemper(options),
        _ => options[Random.Range(0, options.Length)]
    };
}

然后您可以在剧本中如下使用它:

nani
; 基于代词选择。
</p/his/her/their>

; 基于脾气选择。
</t/smiling/frowning/poker face>

; 随机选择。
<//green/red>

选择标签也会公开给本地化文档,允许翻译人员根据需要调整结构以适应目标文化。