> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/usage-examples.md).

# 情绪示例

这些场景展示了 Emotion 系统的配置和脚本 API 如何结合起来满足真实的应用需求。每个场景都是自包含的：先描述 Inspector 设置，然后给出完成行为所需的运行时代码。配置文件和绑定字段引用位于 [Emotion 配置文件](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/emotion-profile.md) 是位于 [情绪输出绑定](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/output-bindings.md)；完整的脚本接口位于 [Emotion 脚本 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/scripting-api.md).

### 场景 1：动态危险响应

**情境：** 一位讲师 NPC 正引导学员进行火灾疏散模拟。当学员进入标记的危险区域时，讲师的表情应迅速切换为恐惧或紧迫，以强化情境的严重性。当学员离开该区域时，表情会恢复为服务器驱动状态。

#### 配置文件设置

打开 `ConvaiEmotionProfile` 分配给讲师 NPC，并调整：

* **`lerpSpeed`** → `12` — 快速上升，让恐惧表情无延迟地出现。
* **`microBurstOvershoot`** → `1.6` — 明显的爆发使过渡更具视觉冲击力。
* **`microBurstDuration`** → `0.2 秒` — 在表情稳定前的短暂爆发。

#### 输出绑定

向以下项添加一个槽位： **Blendshape 绑定**:

| `emotionLabel` | `blendshapeNames`                                                | `weightMultiplier` | `fullBlendshapeWeight` |
| -------------- | ---------------------------------------------------------------- | ------------------ | ---------------------- |
| `恐惧`           | `Brow_Raise_Inner_L, Brow_Raise_Inner_R, Eye_Wide_L, Eye_Wide_R` | `1.0`              | `85`                   |

#### 运行时脚本

```csharp
using Convai.Modules.Emotion.Components;
using UnityEngine;

public sealed class HazardZoneTrigger : MonoBehaviour
{
    [SerializeField] private ConvaiEmotionController instructorEmotion;

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Trainee"))
            instructorEmotion.SetEmotionOverride("fear", 0.9f);
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Trainee"))
            instructorEmotion.ClearEmotionOverride();
    }
}
```

`SetEmotionOverride` 会在服务器当前发送的内容之上叠加恐惧分数。累加器会在配置的 `lerpSpeed`，因此覆盖会迅速但自然地到达。 `ClearEmotionOverride` 在触发器退出时调用，允许服务器发出恢复完全控制的信号。

***

### 场景 2：锁定的欢迎表情

**情境：** 一位迎宾 NPC 站在入职培训模拟的入口处。在欢迎流程期间——在学员开始说话之前——无论后端在连接握手期间发送任何情绪信号，角色都应始终显得温暖且平易近人。

#### 运行时脚本

```csharp
using Convai.Modules.Emotion.Components;
using UnityEngine;

public sealed class WelcomeSequenceController : MonoBehaviour
{
    [SerializeField] private ConvaiEmotionController greeterEmotion;

    private void Start()
    {
        // 从第一帧起保持温和、友好的表情
        greeterEmotion.LockEmotion("joy", 0.65f);
    }

    public void OnWelcomeSequenceComplete()
    {
        // 释放锁定，让角色自然响应对话
        greeterEmotion.UnlockEmotion();
    }
}
```

锁定强度为 `0.65` 会产生可见但不过分夸张的微笑——适合专业场景。 `UnlockEmotion` 会在模拟切换到开放式对话时调用，此时角色开始响应实时 AI 信号。

***

### 场景 3：感知情绪的分支逻辑

**情境：** 在医疗沟通评估中，一位虚拟病人 NPC 在学员的回应被视为冷漠时会变得沮丧。一个导演脚本会监控该 NPC 的情绪状态，如果检测到持续的沮丧，就将场景分支到降温处理路径。

#### 运行时脚本

```csharp
using Convai.Domain.Embodiment.Readings;
using Convai.Modules.Emotion.Components;
using UnityEngine;
using UnityEngine.Events;

public sealed class EmotionBranchDirector : MonoBehaviour
{
    [SerializeField] private ConvaiEmotionController patientEmotion;
    [SerializeField] private float distressThreshold = 0.6f;
    [SerializeField] private float sustainedDistressSeconds = 4f;
    [SerializeField] private UnityEvent onDistressBranchTriggered;

    private bool _branchTriggered;

    private void Update()
    {
        if (_branchTriggered) return;

        EmotionReading reading = patientEmotion.Current;

        bool isSadOrFearful = reading.DominantLabel is "sadness" or "fear"
                              && reading.DominantScore >= distressThreshold;

        if (isSadOrFearful && reading.DominantHoldSeconds >= sustainedDistressSeconds)
        {
            _branchTriggered = true;
            onDistressBranchTriggered.Invoke();
        }
    }
}
```

`DominantHoldSeconds` 跟踪当前主导情绪被连续保持了多长时间。将它与分数阈值结合使用，可以防止短暂峰值触发分支——只有真正持续的沮丧才会推动场景继续。

***

### 场景 4：会话分析日志记录

**情境：** 一个培训平台需要记录会话期间 AI 角色经历的每一次情绪变化，包括原始服务器标签和强度，以便讲师在会后报告中回顾对话的情绪曲线。

#### 运行时脚本

```csharp
using Convai.Domain.DomainEvents.Runtime;
using Convai.Runtime.Components;
using System.Collections.Generic;
using UnityEngine;

public sealed class EmotionSessionLogger : MonoBehaviour
{
    [SerializeField] private ConvaiManager convaiManager;

    private readonly List<string> _emotionLog = new();

    private void OnEnable()
    {
        convaiManager.Events.OnCharacterEmotionChanged += HandleEmotionChanged;
    }

    private void OnDisable()
    {
        convaiManager.Events.OnCharacterEmotionChanged -= HandleEmotionChanged;
    }

    private void HandleEmotionChanged(CharacterEmotionChanged e)
    {
        string entry = $"[{e.Timestamp:HH:mm:ss.fff}] {e.CharacterId}: {e.Emotion} (scale {e.Intensity})";
        _emotionLog.Add(entry);
        Debug.Log(entry);
    }

    public IReadOnlyList<string> GetLog() => _emotionLog;
}
```

`OnCharacterEmotionChanged` 会在每次来自后端的情绪信号触发时执行，早于控制器对其进行平滑或处理。这使分析代码能够访问原始信号，而不是插值后的视觉状态，这对于会话回顾更有意义。

***

### 场景 5：无代码 UI 显示

**情境：** 一位非程序员希望在角色当前情绪发生变化时更新显示该情绪的 UI 标签，而无需编写任何代码。

{% stepper %}
{% step %}

#### 添加事件中继

选择 NPC 的根 GameObject。点击 **添加组件** 并导航至 **Convai → 事件 → Convai Character Event Relay**.

该中继会自动解析 `ConvaiCharacter` 同一 GameObject 上的 **自动解析角色** 切换开关，该开关默认已启用。
{% endstep %}

{% step %}

#### 连接 On Emotion Changed 事件

在 **On Emotion Changed** 上的 Unity Event 列表 `ConvaiCharacterEventRelay`点击 **+**.
{% endstep %}

{% step %}

#### 分配 UI Text 组件

将你的 UI `文本` （或 `TMP_Text`）组件拖入新事件条目的对象字段。
{% endstep %}

{% step %}

#### 选择目标属性

在函数下拉菜单中选择 **Text → string text** （或 **TMP\_Text → string text**).

现在，每当角色的情绪变化时， `情绪` 中的属性 `CharacterEmotionRelayData` 会直接写入标签——无需代码。
{% endstep %}
{% endstepper %}

{% hint style="success" %}
进入 Play Mode 并与角色对话。随着后端发送新的情绪信号，UI 标签会自动更新。
{% endhint %}

{% hint style="info" %}
`ConvaiCharacterEventRelay` 提供原始服务器标签（例如 `"快乐"`）。如果你需要更友好的显示名称（例如 `"Joy"` 而不是 `"快乐"`），请添加一个小的格式化脚本，将原始标签映射为显示字符串，或者在 UnityEvent 目标方法中对该字符串进行后处理。
{% endhint %}

***

### 场景 6：在编辑器中预览表情

**情境：** 你已经为一个新角色添加了 blendshape 槽位，现在希望在进入 Play Mode 之前确认每种情绪是否会将正确的形状驱动到正确的权重。

1. 选择 NPC 的根 GameObject。
2. 在 `ConvaiEmotionController` 组件上，启用 **锁定情绪**.
3. 设置 **锁定的情绪标签** 为你想预览的规范标签（例如 `"愤怒"`).
4. 设置 **锁定强度** 到 `1.0`.

Scene 视图会立即更新——因为 `ConvaiEmotionController` 继承 `[ExecuteAlways]` 自其基类，blendshape 会在编辑模式下应用。切换你的分类体系中的各个标签，直观验证每个槽位的映射。

{% hint style="danger" %}
设置 **锁定情绪** 再切换回 `false` 在用于生产构建之前。该字段是可序列化的——如果它仍处于启用状态，发布版本中的角色将忽略所有后端情绪信号，不会出现运行时错误或警告。
{% endhint %}

### 下一步

有关上述配置文件设置中使用的完整参数参考，请参见 [Emotion 配置文件](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/emotion-profile.md)。有关完整脚本接口，请参见 [Emotion 脚本 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/scripting-api.md)。如果任何场景未产生预期结果，请参见 [情绪故障排查](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/troubleshooting-and-diagnostics.md).

{% content-ref url="/pages/5a9247365092d958f2d539ae98bdfe69f72df091" %}
[情绪配置文件](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/emotion-profile.md)
{% endcontent-ref %}

{% content-ref url="/pages/39d161d99d04e6ca98725c740d134ccb5eac9e73" %}
[情绪脚本 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/scripting-api.md)
{% endcontent-ref %}

{% content-ref url="/pages/65ec9decd2473b72bc06bf3c946f3008c8528dda" %}
[排查情绪问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/troubleshooting-and-diagnostics.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/emotion/usage-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
