脚本 API 参考
读取实时情绪状态,从代码驱动表情,响应情绪事件,并在脚本序列中将角色锁定到特定情绪。
运行时控制与观察情绪状态
Emotion 系统提供两条不同路径,用于在运行时响应和控制情绪状态。The Inspector 路径 使用 ConvaiCharacterEventRelay —— 一个将情绪变化回调以标准 Unity Events 形式公开的组件,无需编写代码。The 脚本路径 使用 ConvaiEmotionController 直接提供完整的 C# API,用于读取实时状态、注入覆盖和锁定表情。两条路径可同时使用。
Inspector 路径 — ConvaiCharacterEventRelay
ConvaiCharacterEventRelay 是一个 MonoBehaviour,用于将角色回调桥接到 Unity Events,使设计师无需编写任何代码即可完全在 Inspector 中配置情绪反应。
添加组件: Convai → 事件 → Convai Character Event Relay
将其放置在场景中的任意 GameObject 上。它会自动找到 ConvaiCharacter 同一个 GameObject 上的,或者你也可以通过 角色 字段中。
Inspector 字段
角色
(无)
可选地显式引用一个 ConvaiCharacter。留空以使用自动解析。
自动解析角色
true
启用后,中继器会找到一个 ConvaiCharacter 并自动定位到同一 GameObject 上。
OnEmotionChanged 事件
中继器公开一个 On Emotion Changed Unity 事件,每当角色的情绪信号发生变化时都会触发。该事件传递一个 CharacterEmotionRelayData 载荷:
CharacterId
string
角色的唯一标识符。
CharacterName
string
角色的显示名称(回退为 GameObject 名称)。
情绪
string
原始服务器标签(例如 "快乐").
强度
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", "愤怒").
DominantScore
float
经平滑和突发处理后的主导情绪归一化分数 [0–1]。
AllScores
IReadOnlyDictionary<string, float>
以规范标签为键的完整分数表。分类法中的每种情绪都有一项。
MouthInfluence
float
LipSync 合成器在非说话帧中用于混合嘴型的提示值 [0–1]。
DominantHoldSeconds
float
当前主导标签连续保持的实际秒数。
IsNeutral
bool
当主导标签为 "neutral" 或当 DominantScore ≤ 0.
NeutralLabel
const string
字符串常量 "neutral".
Inspector 锁定
控制器有三个序列化字段,可让你直接在 Inspector 中将表情固定为某个特定情绪——这在创作和调试时很有用,或者当你想在不进入 Play Mode 的情况下在 Scene 视图中预览 blendshape 槽位结果时也很有用。
lockEmotion
bool
false
启用后,所有传入的服务器情绪事件都会被忽略,角色将保持锁定的情绪。
lockedEmotionLabel
string
"neutral"
在……期间保持的规范分类标签 lockEmotion 处于启用状态。
lockedIntensity
float
1.0
锁定情绪的强度 [0–1]。
ConvaiEmotionController 为 [ExecuteAlways]。设置 lockEmotion = true 在 Inspector 中会立即更新 Scene 视图中的 blendshapes,无需进入 Play Mode。这使其成为验证槽位映射是否在角色网格上产生正确视觉结果的实用工具。
lockEmotion 是一个 序列化字段 —— 其值会与场景或 prefab 一起保存。如果你在 Inspector 中保持启用并忘记重置,角色将在正式构建中静默忽略所有实时情绪信号。发布前务必将其禁用。
SetEmotionOverride / ClearEmotionOverride
SetEmotionOverride 在服务器发送的内容之上向累加器注入额外分数。该覆盖仍受平滑处理影响——它会以 lerpSpeed的方式混合进去,而不是瞬间生效。当你的应用逻辑需要根据模拟内事件放大或引导情绪时使用此功能。
ClearEmotionOverride 移除覆盖,并让累加器恢复到由服务器驱动的状态。回切过程会被平滑处理。
LockEmotion / UnlockEmotion
LockEmotion 完全绕过累加器,直接将角色切换到某个特定表情并保持在那里,无论服务器发送什么都不受影响。当你在脚本序列或过场动画期间需要一个有保证、稳定的表情时使用。
UnlockEmotion 解除锁定。累加器从中立状态恢复,并重新开始响应服务器事件。
API 参考:
在代码中监听情绪变化事件
若要响应后端发送的每个新情绪——用于日志记录、分析或自适应场景逻辑——请订阅 OnCharacterEmotionChanged on ConvaiManager.Events。这是标准 C# 事件;无需管理订阅令牌。
CharacterEmotionChanged 属性
CharacterId
string
情绪发生变化的角色的唯一标识符。
情绪
string
原始服务器标签(例如 "快乐",而不是 "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.
时间戳
DateTime
事件创建时的 UTC 时间戳。
CharacterEmotionChanged.Emotion 包含 原始服务器标签 (例如 "快乐"),而不是规范分类标签("joy")。如果你需要规范标签——例如,要在……中查找分数 AllScores —— 请通过分类法解析: taxonomy.TryResolve(e.Emotion, out EmotionDescriptor descriptor).
IEmotionStateSource 接口
仅需要读取情绪状态、而不需要控制覆盖或锁定的代码,应依赖于 IEmotionStateSource 而不是具体的 ConvaiEmotionController。这样可将依赖降到最低,并使消费类更易于独立测试。
结论
最后更新于
这有帮助吗?