For the complete documentation index, see llms.txt. This page is also available as Markdown.

叙事设计使用示例

四个完整的叙事设计示例,从单触发欢迎序列到带动态反馈的自适应多分段场景。

以下示例展示了如何组合 ConvaiNarrativeDesignManager, ConvaiNarrativeDesignTrigger,和 IConvaiNarrativeDesign 成完整、可运行的设置。它们按从简单到高级排序,并涵盖不同领域,以展示 Narrative Design 支持的广度。每个示例都是独立的——从与你当前复杂度级别最匹配的那个开始。

示例 1:脚本化欢迎序列

复杂度: 初级 | 激活模式: 手动 | 使用的功能: 管理器、触发器(手动)、一个模板键

场景: 一位访客来到接待台。UI 中的“Start”按钮通过发送一个单独的触发器来启动体验,使角色从空闲状态进入主动欢迎部分。

设置

1

准备场景

添加 ConvaiNarrativeDesignManager 到角色 GameObject,并从仪表板同步各章节。你至少需要两个章节:一个空闲章节(角色在此等待)和一个欢迎章节(角色在此开始体验)。

2

在会话开始前设置访客姓名

在开始会话之前,发送一个模板键,以便角色可以按姓名称呼访客:

public class ReceptionController : MonoBehaviour
{
    [SerializeField] private ConvaiNarrativeDesignManager _narrativeManager;
    [SerializeField] private string _visitorName;

    private void Start()
    {
        _narrativeManager.UpdateAndSendTemplateKey("VisitorName", _visitorName);
    }
}
3

添加一个手动触发器

添加 ConvaiNarrativeDesignTrigger 到任意 GameObject(它不会出现在世界中——由 UI 驱动)。设置 激活模式 设为 手动 并从仪表板中获取/选择欢迎触发器。

4

连接 UI 按钮

在 Button 组件的 On Click () 事件中,指定 ConvaiNarrativeDesignTrigger 并选择 ConvaiNarrativeDesignTrigger.InvokeTrigger.

5

连接章节事件

在管理器的 叙事章节 列表中,找到欢迎章节条目并添加一个 OnSectionStart 监听器。将其指向欢迎开始时场景中应发生变化的内容——例如,启用姓名牌 UI 或启动环境动画。

运行时会发生什么: 玩家点击 Start → InvokeTrigger() 将触发器发送到后端 → 图表移动到欢迎章节 → OnSectionStart 在欢迎章节入口处触发 → 角色开始欢迎。

示例 2:分支对话

复杂度: 中级 | 激活模式: 手动(代码驱动) | 使用的功能: 管理器、 IConvaiNarrativeDesign, InvokeSpeech、多个模板键

场景: 一个导览助手可以引导用户浏览三个独立的主题区域(设施、系统访问、政策)。主题选择由 UI 按钮驱动,用户可以在主题之间自由切换。每个主题之后都支持开放式后续提问。

设置

在管理器中同步所有主题章节。无需 ConvaiNarrativeDesignTrigger 组件——触发器直接通过 IConvaiNarrativeDesign.

public class OrientationController : MonoBehaviour
{
    [SerializeField] private ConvaiCharacter _character;
    [SerializeField] private ConvaiNarrativeDesignManager _narrativeManager;
    [SerializeField] private TextMeshProUGUI _activeTopicLabel;

    private void OnEnable()
    {
        _character.NarrativeDesign.OnSectionChanged += OnSectionChanged;
    }

    private void OnDisable()
    {
        _character.NarrativeDesign.OnSectionChanged -= OnSectionChanged;
    }

    // 由 UI 按钮调用
    public void SelectTopic(string triggerName)
    {
        _character.NarrativeDesign.InvokeTrigger(triggerName);
    }

    // 由自由文本输入框的提交事件调用——纯文本上下文注入
    // 角色会用自己的话自然回应
    public void AskFollowUp(string userQuestion)
    {
        _character.NarrativeDesign.InvokeSpeech(userQuestion);
    }

    // 当需要脚本化公告时调用——角色会逐字说出这段文本
    public void AnnounceToUser(string announcement)
    {
        _character.NarrativeDesign.InvokeSpeech($"<speak>{announcement}</speak>");
    }

    private void OnSectionChanged(string previous, string next)
    {
        // 更新面包屑 UI——从管理器中查找可读名称
        if (_narrativeManager.FindSectionConfig(next) is { } cfg)
            _activeTopicLabel.text = cfg.SectionName;
    }
}

在 Inspector 中为按钮分配触发器名称: "TopicFacilities", "TopicSystemsAccess", "TopicPolicies".

所有触发器上的 TriggerOnce = false 设置为 false,以便用户可以重新访问任意主题。会话打开前从表单发送模板键(UserName, Department)使用 UpdateTemplateKeys.

InvokeSpeech 有两种模式:纯文本会让角色用自己的话自然回应(适用于自由文本后续提问);将消息包裹在 <speak> 标签中会让角色逐字说出该文本(适用于脚本化公告或精确提示)。这两种模式都不会推进图表。请参见 控制角色语音 以获取完整参考。

示例 3:基于接近触发的展厅导览

复杂度: 中级 | 激活模式: 接近 | 使用的功能: 管理器、触发器(接近)、区域事件、批量模板键

场景: 一个产品展厅有五个展示站点。访客走近每个站点时,主持角色就开始讲解该产品。每个站点都是独立的,可以按任意顺序参观。

设置

为每个站点创建一个 ConvaiNarrativeDesignTrigger 。对于每个站点:

  • 激活模式: 接近

  • 接近半径: 根据站点大小调整(在 Scene 视图中显示为绿色球体 gizmo)

  • 仅触发一次: true

  • 场景加载时重置: true (这样每次参观时导览都会重置)

通过模板键连接站点特定上下文。从一个 ScriptableObjectStart():

使用 OnPlayerEnterZone 用于高亮产品模型(例如启用轮廓着色器)。使用 OnPlayerExitZone 来移除高亮。

示例 4:带动态反馈的自适应场景

复杂度: 高级 | 激活模式: 代码驱动 | 使用的功能: 管理器、 IConvaiNarrativeDesign, OnSectionDataReceived, BehaviorTreeConstants、动态模板键、重做流程

场景: 一个技术技能评估器运行一个多步骤场景。每完成一步,学习者的表现都会被评分。角色的引导程度和场景的难度会根据当前累计得分动态调整。该场景可以重新尝试,并重置所有状态。

会话生命周期

实现

BehaviorTreeConstants 是你在 Convai 仪表板中按章节编写的 JSON 字符串。它携带你希望从图表注入到 Unity 的任何数据——时间限制、评分阈值、提示标志或其他场景参数。SDK 会在每个 NarrativeSectionData 载荷中传递它。

BehaviorTreeCodeBehaviorTreeConstants 在 SDK 侧为只读。它们携带在 Convai 仪表板中编写的数据,无法在 Unity 运行时修改。

下一步

叙事设计脚本参考叙事设计故障排查

最后更新于

这有帮助吗?