情绪脚本 API
情绪脚本接口参考——ConvaiEmotionController、EmotionReading、覆盖和锁定方法、C# 事件以及 IEmotionStateSource。
Emotion 系统在运行时提供两条不同的路径来响应和控制情绪状态。The 检视器路径 使用 ConvaiCharacterEventRelay —— 一个将情绪变化回调作为标准 Unity Event 暴露出来的组件,无需编写代码。The 脚本路径 使用 ConvaiEmotionController 直接使用,提供完整的 C# API,用于读取实时状态、注入覆盖以及锁定表情。两条路径可以同时使用。
检视器路径 — ConvaiCharacterEventRelay
ConvaiCharacterEventRelay 是一个 MonoBehaviour,它将角色回调桥接到 Unity Event,允许设计师完全在检视器中配置情绪反应,无需编写任何代码。
添加组件: Convai → Events → Convai Character Event Relay
将其放置在场景中的任意 GameObject 上。它会自动找到 ConvaiCharacter ,位于同一个 GameObject 上,或者你也可以通过 Character 字段从另一个 GameObject 分配角色。
检视器字段
Character
(无)
对一个 ConvaiCharacter的可选显式引用。留空则使用自动解析。
自动解析角色
true
启用后,继电器会自动找到一个 ConvaiCharacter 位于同一个 GameObject 上的对象。
OnEmotionChanged 事件
该继电器公开一个 On Emotion Changed Unity Event,它会在角色的情绪信号发生变化时触发。该事件会传递一个 CharacterEmotionRelayData 载荷:
CharacterId
string
角色的唯一标识符。
CharacterName
string
角色的显示名称(若无则回退到 GameObject 名称)。
Emotion
string
原始服务器标签(例如 "happy").
强度
int
后端发送的 1–3 整数刻度。
示例连线: 添加一个 ConvaiCharacterEventRelay 到你的 NPC 的 GameObject。 在 On Emotion Changed 列表中,单击 +,将一个 UI Text 组件拖入对象字段,并选择 Text.text —— 标签将在每次情绪变化时自动更新。
ConvaiCharacterEventRelay 在进行分类法解析或平滑处理之前,会在原始服务器标签上触发。可用于 UI 显示、音频提示或简单的分支逻辑。对于带有分数和保持时间的平滑、解析后状态,请改用 ConvaiEmotionController.Current ,从脚本中访问。
从脚本访问控制器
该 ConvaiEmotionController 组件可以通过其具体类型获取,也可以通过 IEmotionStateSource 接口获取。当你希望将代码与特定组件实现解耦时,请使用接口:
读取当前情绪状态
ConvaiEmotionController.Current 返回一个 EmotionReading —— 每帧根据累加器输出重建的不可变快照。可在 Update 中轮询,或通过任意事件对其做出反应。
EmotionReading 属性和方法
DominantLabel
string
得分最高情绪的规范化标签(例如 "joy", "anger").
DominantScore
float
平滑和突发处理后,主导情绪的归一化分数 [0–1]。
AllScores
IReadOnlyDictionary<string, float>
按规范化标签键控的完整分数表。分类法中的每种情绪都有一个条目。本帧没有贡献的情绪得分为 0.
嘴部影响
float
在非说话帧期间被 LipSync 合成器用于混合口型的 [0–1] 提示值。
主导标签已持续保持的实际秒数。
float
当前主导标签连续保持的实时时钟秒数。
IsNeutral
bool
true 当主导标签为 "neutral" 或当 DominantScore ≤ 0.
NeutralLabel
const string
字符串常量 "neutral".
GetScore(string canonicalLabel)
float
返回给定规范化标签的平滑分数,若不存在则返回 0 。
CopyScoresTo(IDictionary<string, float> destination)
void
将完整分数表复制到调用方拥有的字典中。复制前会清空目标。
作者期锁定
控制器有三个序列化字段,可直接在检视器中将表情固定为某种特定情绪——这在制作和调试时很有用,或者可在不进入 Play Mode 的情况下,在 Scene 视图中预览 blendshape 轨道结果。
lockEmotion
bool
false
启用后,所有传入的服务器情绪事件都会被忽略,角色会保持锁定的情绪。
lockedEmotionLabel
string
"neutral"
在 lockEmotion 处于激活状态时保持的规范化分类标签。
lockedIntensity
float
1.0
锁定情绪的强度 [0–1]。
lockEmotion 是一个 序列化字段 —— 它的值会随场景或预制体一起保存。如果你保持启用却忘记重置,角色将在生产构建中悄无声息地忽略所有实时情绪信号,不会有运行时错误或警告。构建前务必将其禁用。
ConvaiEmotionController 继承自 [ExecuteAlways] 其基类。设置 lockEmotion = true 在检视器中会立即更新 Scene 视图里的 blendshape,而无需进入 Play Mode。这使它成为验证插槽映射是否在角色网格上产生正确视觉结果的实用工具。
SetEmotionOverride 和 ClearEmotionOverride
SetEmotionOverride 会在服务器发送内容之上向累加器注入额外分数。该覆盖仍然会经过平滑处理——它会以 lerpSpeed的速度混入,而不是瞬间生效。当你的应用逻辑需要响应场景内事件来增强或引导情绪时,请使用它。
ClearEmotionOverride 会移除覆盖并将累加器恢复为由服务器驱动的状态。返回过程是平滑的。
LockEmotion 和 UnlockEmotion
LockEmotion 会完全绕过累加器,将角色立即切换到某个特定表情并保持在那里,无论服务器发送什么都不受影响。当你需要在脚本化序列中获得可保证、稳定的表情时,请使用它。
UnlockEmotion 会释放锁定。累加器将从中性状态恢复,并再次开始响应服务器事件。
API 签名:
订阅情绪变化事件
若要对后端发送的每一种新情绪作出反应——用于日志记录、分析或自适应场景逻辑——请订阅 OnCharacterEmotionChanged 在 ConvaiManager.Events上。这是一个标准的 C# 事件;在 OnEnable 中订阅,并在 OnDisable.
CharacterEmotionChanged 属性
CharacterId
string
情绪发生变化的角色的唯一标识符。
Emotion
string
原始服务器标签(例如 "happy",而不是规范化的 "joy").
强度
int
后端发送的 1–3 整数刻度(已截断)。
NormalizedIntensity
float
(Intensity - 1) / 2f —— 将 1–3 范围映射到 [0, 1]。
IsNeutral
bool
true 如果情绪字符串为 "neutral".
IsHighIntensity
bool
true 如果 Intensity >= 3.
IsLowIntensity
bool
true 如果 Intensity <= 1.
Timestamp
DateTime
事件创建时的 UTC 时间戳。
CharacterEmotionChanged.Emotion 包含 原始服务器标签 (例如 "happy"),而不是规范化的分类法标签("joy")。如果你需要规范化标签——例如,要在 AllScores 中查找分数——请通过分类法解析它: taxonomy.TryResolve(e.Emotion, out EmotionDescriptor descriptor).
IEmotionStateSource 接口
仅需要读取情绪状态、而不需要控制覆盖或锁定的代码,应依赖于 IEmotionStateSource ,而不是具体的 ConvaiEmotionController。这可以保持依赖最小,并使消费类更容易测试。
下一步
情感示例排查情感问题最后更新于
这有帮助吗?