> 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-unreal-engine-plugin/features/emotion/how-the-emotion-system-works.md).

# 情绪系统的工作原理

当 Convai 角色响应时，Convai 会分析生成的语音，并连同音频一起返回一个情绪状态。Convai Unreal Engine 插件会将该状态存储在 `UConvaiChatbotComponent`中，通过 Blueprint 公开每个情绪的浮点分数，并在状态每次更新时触发一个事件。

### 关键概念

| 概念                           | 它是什么                                                                                              |
| ---------------------------- | ------------------------------------------------------------------------------------------------- |
| `UConvaiChatbotComponent`    | 为单个角色持有情绪状态的 Blueprint 组件。分数和状态相关的 API 都在这里。                                                      |
| `EBasicEmotions`             | 七种可见情绪类别的枚举（`快乐`, `平静`, `害怕`, `惊讶`, `悲伤`, `无聊`, `愤怒`).                                            |
| `EEmotionIntensity`          | 三个强度级别的枚举（`较低强度`, `基础`, `较高强度`）用于 `Force Set Emotion` ——不用于服务器分数路径。                               |
| `EmotionOffset`              | 一个 `float` 在截断前添加到每个服务器驱动的情绪分数上的偏置。会将感知到的强度上调或下调。                                                 |
| `LockEmotionState`           | 一个 `bool` 用于阻止传入的服务器情绪更新并抑制 `情绪状态变更` 服务器路径上的更新，直到解除为止。                                            |
| `OnEmotionStateChangedEvent` | 在情绪状态变化时于游戏线程触发的委托——Blueprint 表情逻辑的主要挂钩。                                                          |
| `GetEmotionScore`            | 返回当前 `float` 分数（`0.0`–`1.0`）对应某一 `EBasicEmotions` 类别。可用它驱动 morph target 或 Animation Blueprint 变量。 |

### 情绪类别

该插件将情绪建模为由以下内容定义的七种可见类别： `EBasicEmotions`:

| 枚举值  | Blueprint 显示名称 |
| ---- | -------------- |
| `快乐` | `快乐`           |
| `信任` | `平静`           |
| `恐惧` | `害怕`           |
| `惊讶` | `惊讶`           |
| `悲伤` | `悲伤`           |
| `厌恶` | `无聊`           |
| `愤怒` | `愤怒`           |

当前的 `bot-emotion` 数据包路径在每次更新时提供一个情绪标签和一个缩放值。每次更新都会覆盖之前的状态，除非 `LockEmotionState` 是 `true` （参见 [锁定情绪状态](#locking-emotion-state)).

### 服务器情绪标签

服务器会连同强度刻度（`1`–`3`）一起发送一个简短的情绪标签字符串。插件会将这些标签通过 `EBasicEmotions` 映射为 `GetTTSEmotion`枚举值。可识别的八种标签如下：

| 服务器标签        | 映射到（`EBasicEmotions`) |
| ------------ | --------------------- |
| `"Joy"`      | `快乐`                  |
| `"Calm"`     | `信任`                  |
| `"Fear"`     | `恐惧`                  |
| `"Surprise"` | `惊讶`                  |
| `"Sadness"`  | `悲伤`                  |
| `"Bored"`    | `厌恶`                  |
| `"Anger"`    | `愤怒`                  |
| `"Neutral"`  | `无` （无活动情绪）           |

当服务器更新到达时，插件会先重置所有情绪分数，然后写入解析得到的类别分数。插件无法识别的标签会映射到 `无` ——分数仍会被重置，因此角色会返回中性分数表，而不是保留之前的表情。如果某个特定情绪在对话中从未出现，请确认 Convai 发送的是上面列出的标签之一——参见 [排查情绪问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/emotion/troubleshoot-emotion.md).

### 情绪分数

每个类别都有一个范围为 `0.0`–`1.0`的浮点分数。使用 `获取情绪分数` (`EBasicEmotions Emotion`）上的 `UConvaiChatbotComponent`.

#### 服务器驱动的分数

在服务器路径上，插件会从 `bot-emotion` 数据包中解析情绪字符串和缩放值，将缩放值除以 `3`，再加上 `EmotionOffset`，并将结果截断为 `0.0`–`1.0`。缩放值为 `1` 得到的结果大约为 `0.33` 在偏移前；缩放值为 `3` 得到 `1.0` 在偏移前。

该 `EEmotionIntensity` 倍数（`0.25`, `0.60`, `1.00`）仅适用于 `Force Set Emotion`，不适用于服务器驱动的更新。

#### EmotionOffset

该 `EmotionOffset` 上的属性 `UConvaiChatbotComponent` 当服务器驱动的情绪更新到达时，会将所有计算出的分数按固定值偏移。源代码注释说明了一个有用的范围： `-1` 设为 `1`:

* 正偏移会放大每种情绪的感知强度。
* 负偏移会减弱它。
* 分数始终会被截断到 `0.0`–`1.0` ，在应用偏移后。

`EmotionOffset` 仅适用于服务器驱动的更新。它 **不** 不适用于通过 `Force Set Emotion` ——该函数使用 `EEmotionIntensity` 倍数本身。

### 将分数应用到面部

插件不会在服务器情绪路径上填充现成的 morph target 映射。要显示表情，请使用 `获取情绪分数` 读取分数，并使用 `Set Morph Target` 在 Blueprint 中应用它们，或者用分数变量驱动 Animation Blueprint 的混合姿势。将每个 `EBasicEmotions` 类别映射到角色 Skeletal Mesh 上的 morph target 名称。

### 锁定情绪状态

设置 `LockEmotionState` 设为 `true` 在 `UConvaiChatbotComponent` 会阻止传入的服务器更新更改当前情绪。在服务器路径上， `OnEmotionReceived` 会在更新状态或广播之前返回 `情绪状态变更`，

锁定时状态保留当时的值——这些值可能来自先前的服务器更新，或者来自一次 `Force Set Emotion` 调用——直到 `LockEmotionState` 被重新设为 `false`. `Force Set Emotion` 和 `Reset Emotion State` 在锁定期间仍然会更新状态并触发事件。

当你希望角色在过场动画或电影化演出期间保持特定表情，而不受 Convai 发送内容影响时，这很有用。

{% hint style="warning" %}
确认 `LockEmotionState` 被重置为 `false` ，否则角色会一直保持锁定的表情，直到你解锁它。
{% endhint %}

### 强制设置情绪

`Force Set Emotion (EBasicEmotions BasicEmotion, EEmotionIntensity Intensity, bool ResetOtherEmotions)` 会从 Blueprint 覆盖情绪状态，而无需等待服务器更新。当 `ResetOtherEmotions` 是 `true`时，其他所有情绪分数都会先清零。当 `false`时，强制设置的分数会替换同类别的分数，并保持其他类别不变。

应用的分数等于所选级别的 `EEmotionIntensity` 倍数（`较低强度` = `0.25`, `基础` = `0.60`, `较高强度` = `1.00`). `EmotionOffset` 不会应用。

### 状态变更事件

`情绪状态变更` 会在情绪状态由服务器更新时在游戏线程上触发（未锁定时）， `Force Set Emotion`，还是 `Reset Emotion State`。其签名会提供聊天机器人组件和一个交互玩家组件引脚——在当前插件中， **Interacting Player Component** 输出始终为 `null` 在所有路径上都是。使用前请先对该引脚进行空值检查。

下图展示了从服务器传递到分数计算再到 Blueprint 处理器的完整流程：

```mermaid
graph TD
    A["Convai"] -- "情绪标签 + 1–3 级缩放" --> B["标签 → EBasicEmotions\n映射"]
    B -- "缩放值 / 3 + EmotionOffset\n截断到 0–1" --> C["UConvaiChatbotComponent\nEmotionState"]
    C -- "OnEmotionStateChangedEvent" --> D["Blueprint 处理器"]
    D -- "GetEmotionScore()" --> E["设置 Morph Target / AnimBP"]
    F["Force Set Emotion"] -- "EEmotionIntensity\n倍数（无偏移）" --> C
    G["LockEmotionState = true"] -- "阻止服务器路径" --> C
```

### 相关页面

{% content-ref url="/pages/9ac48061a03a0400ae6e1769df358c2fb2a82536" %}
[Emotion Blueprint 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/emotion/emotion-blueprint-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/83566839f3555aa1855858bb1bc0c20ed5a973cc" %}
[情绪示例](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/emotion/emotion-examples.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-unreal-engine-plugin/features/emotion/how-the-emotion-system-works.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.
