For the complete documentation index, see llms.txt. This page is also available as Markdown.

录制并回放口型同步

在 Convai 对话期间捕获实时口型同步序列,并在过场动画、缓存响应或离线预览中稍后回放,而无需重新流式传输。

UConvaiFaceSyncComponent 录制 API 让你能够捕获实时对话中到达的 blendshape 帧,并在不重新从 Convai 进行流式传输的情况下按需回放。它适用于同一段口型同步序列会反复播放的过场动画、在响应被触发之前进行预热,或者用于调试以及面部动画的离线预览。

何时使用录制 API

使用场景
方法

带固定角色台词的过场动画

在开发期间录制一次,保存该序列,并在过场动画中回放

预热的响应缓存

首次播放时录制响应,后续相同响应直接回放

离线面部动画预览

在 PIE 会话期间录制,使用以下方法检查帧数据: GetCurrentFrame()

实时流式传输(实时对话)

不要使用录制 API——AnimGraph 节点会自动处理实时帧

前提条件

  • Actor 具有一个 Convai 面部同步 组件和一个可工作的 Convai 聊天机器人 组件。

  • 该角色在对话时已经会生成口型同步(如果没有,请参见 口型同步快速入门 )。

录制一个序列

1

在发言开始前启动录制

调用 StartRecordingLipSync()UConvaiFaceSyncComponent 实例。从这一刻起,Convai 传来的每一帧 blendshape 数据都会在应用到面部的同时被内部缓存。

// 伪代码
UConvaiFaceSyncComponent* FaceSync = MyCharacter->FindComponentByClass<UConvaiFaceSyncComponent>();
if (FaceSync)
{
    FaceSync->StartRecordingLipSync();
}
2

让角色说话

像平常一样触发一次对话。角色会说话,面部也会动画化。组件会在后台捕获传入的帧——录制期间不需要额外调用。

3

停止录制并保存结果

当发言结束时,调用 FinishRecordingLipSync()。该方法会停止捕获并返回一个 FAnimationSequenceBP ,其中包含按帧索引排列的完整 blendshape 帧列表、总时长以及帧率。

// 伪代码
FAnimationSequenceBP CachedSequence = FaceSync->FinishRecordingLipSync();

将这个值存为 Actor 或组件上的成员变量,以便之后回放。此时你已经拥有了在该轮对话中播放过的完整面部动画。

回放已录制的序列

调用 PlayRecordedLipSyncUConvaiFaceSyncComponent 实例来回放已保存的序列。组件会将录制的帧精确地喂给 AnimGraph 节点,就像在实时流中那样,而且不需要当前有活动的 Convai 对话流。

PlayRecordedLipSync 参数

参数
类型
描述

RecordedLipSync

FAnimationSequenceBP

FinishRecordingLipSync.

StartFrame

int32

要回放的第一帧索引。传入 0 以从头开始。

EndFrame

int32

要回放的最后一帧索引。传入 -1 以播放到序列末尾。

OverwriteDuration

float

覆盖序列中以秒为单位存储的播放时长。传入 0.0 以使用原始时长。

PlayRecordedLipSync 返回 booltrue 如果序列成功开始,则返回 false 如果序列为空或无效、录制仍在进行中, StartFrame 大于最后一帧索引,或者 EndFrame 大于 0 且小于 StartFrame.

监控播放状态

在录制序列播放时,使用这些 C++ 方法来观察组件:

方法
返回
描述

IsPlaying() const

bool

true 当组件正在主动回放来自录制序列或实时序列的帧时。

GetCurrentFrame()

TMap<FName, float>

当前正在应用的帧的 blendshape 名称到权重的映射。适合用同一份数据驱动辅助系统。

C++ 示例流程

典型的过场动画用法如下:

回放一个序列不会重新触发音频。请单独播放匹配的音频片段,并对齐播放开始时间,以保持面部和声音同步。

下一步

Face Sync 组件参考口型同步使用示例

最后更新于

这有帮助吗?