> 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 会分析生成的语音，并连同音频一起返回一个情绪状态。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 显示名称 |
| ----------- | -------------- |
| `喜悦`        | `快乐`           |
| `信任`        | `平静`           |
| `恐惧`        | `害怕`           |
| `惊讶`        | `惊讶`           |
| `悲伤`        | `悲伤`           |
| `厌恶`        | `无聊`           |
| `愤怒`        | `愤怒`           |

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

### 服务器情绪标签

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

| 服务器标签   | 映射到（`EBasicEmotions`) |
| ------- | --------------------- |
| `“Joy”` | `喜悦`                  |
| `"平静"`  | `信任`                  |
| `"恐惧"`  | `恐惧`                  |
| `"惊讶"`  | `惊讶`                  |
| `"悲伤"`  | `悲伤`                  |
| `"无聊"`  | `厌恶`                  |
| `"愤怒"`  | `愤怒`                  |
| `"中性"`  | `None` （无活动情绪）        |

当服务器更新到来时，插件会先重置所有情绪分数，然后为解析出的类别写入该分数。插件无法识别的标签会映射到 `None` ——分数仍会被重置，因此角色会回到中性分数表，而不是保留之前的表情。如果在对话中某种特定情绪从未出现，请确认 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`.

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

在服务器路径上，插件会从 `机器人情绪` 数据包中解析情绪字符串和缩放值，将该缩放值除以 `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 映射。要显示表情，请使用 `获取情绪分数` 读取分数，并在 Blueprint 中通过 `Set Morph Target` 将其应用到 morph target，或者从分数变量驱动 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`为 true 时，所有其他情绪分数会先清零。当 `false`为 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["Set Morph Target / AnimBP"]
    F["Force Set Emotion"] -- "EEmotionIntensity\n倍增器（无偏移）" --> C
    G["LockEmotionState = true"] -- "阻止服务器路径" --> C
```

### 相关页面

{% content-ref url="/pages/9ac48061a03a0400ae6e1769df358c2fb2a82536" %}
[情绪 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
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>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
