事件音效组件
事件音效组件(UEventSoundComponent)是一个 UActorComponent,用于监听文本动画器的字符揭示事件并播放对应的音效。它为打字机效果提供逐字符音效反馈,并支持标点符号延迟以模拟自然的朗读节奏。
功能概述
| 功能 | 说明 |
|---|---|
| 逐字符音效 | 每个字符揭示时可播放不同的音效 |
| 标点延迟 | 在标点符号(逗号、句号等)后插入短暂停顿 |
| 性能控制 | 每帧最多处理 MaxSoundsPerTick 个音效(默认 8,控制 ≤1ms) |
核心 API
音效映射
// 为指定字符设置音效
void SetSoundForCharacter(int32 Character, TSoftObjectPtr<USoundBase> Sound);
// 获取指定字符的音效
TSoftObjectPtr<USoundBase> GetSoundForCharacter(int32 Character) const;
// 移除指定字符的音效映射
void RemoveSoundForCharacter(int32 Character);
// 清空所有音效映射
void ClearAllSounds();
标点延迟
// 设置标点字符的额外延迟(秒)
void SetPunctuationDelayForCharacter(int32 Character, float DelaySeconds);
// 获取标点延迟值
float GetPunctuationDelayForCharacter(int32 Character) const;
// 重置为默认配置
void ResetPunctuationDelaysToDefault();
// 清空所有延迟配置
void ClearPunctuationDelays();
绑定管理
// 自动查找并绑定同 Actor 的 TextAnimator
void BindToAnimator();
// 解绑当前 Animator
void UnbindFromAnimator();
// 直接设置 Animator 实例(替代自动绑定)
void SetAnimator(UTextAnimator* InAnimator);
配置属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
bAutoBindToAnimator | bool | true | BeginPlay 时自动绑定同 Actor 上的 TextAnimator |
MaxSoundsPerTick | int32 | 8 | 每帧最多处理的音效数量(控制 CPU 开销) |
内部机制
音效队列
组件维护一个 FIFO 音效队列(PendingSoundQueue),在 TickComponent() 中逐帧处理:
HandleOnCharacterRevealed()将字符加入队列ProcessSoundQueue()每帧从队列头部取最多MaxSoundsPerTick个字符播放音效- 通过
PendingSoundHead索引实现高效的出队操作(无需实际移除元素)
标点冷却
PunctuationCooldownRemaining 计时器在遇到标点字符时设置,在此期间暂停音效处理,实现自然的朗读停顿。
音效缓存
CharacterSoundMap(TMap<TCHAR, TSoftObjectPtr<USoundBase>>)存储字符到音效的映射。LoadedSoundCache(TMap<int32, TObjectPtr<USoundBase>>)缓存已异步加载到内存的音效对象,避免重复加载。
NOTE
TCHAR不可作为UPROPERTY的键类型,因此公开 API 使用int32参数,内部映射使用TCHAR键。
使用示例
蓝图使用:
- 在 Actor 蓝图中添加
UEventSoundComponent - 在
BeginPlay中调用BindToAnimator()(或依赖bAutoBindToAnimator) - 使用
SetSoundForCharacter()为常用字符配置音效 - 使用
SetPunctuationDelayForCharacter()为标点配置延迟
C++ 使用:
// 创建并配置音效组件
UEventSoundComponent* SoundComp = CreateDefaultSubobject<UEventSoundComponent>(TEXT("TextSound"));
SoundComp->bAutoBindToAnimator = true;
// 为所有元音字母设置音效(模拟语音合成)
SoundComp->SetSoundForCharacter('a', VowelSound);
SoundComp->SetSoundForCharacter('e', VowelSound);
// ...