事件系统

Texturge 通过 BlueprintNativeEvent(覆盖事件)与 BlueprintAssignable 委托(绑定事件)在动画生命周期关键节点提供扩展点。

BuildDefaultAnimation 事件

适用场景:在动画蓝图事件图中重写烘焙逻辑,根据文本内容动态编排动画。

BuildDefaultAnimationUTextAnimInstance 上的 BlueprintNativeEvent,烘焙时由 FAnimationCompiler::BakeAllStages 调用。

签名

UFUNCTION(BlueprintNativeEvent,
    meta = (DisplayName = "构建默认动画", ReturnDisplayName = "Baked Stage"))
FBakedStage BuildDefaultAnimation(
    UPARAM(DisplayName = "Glyph Count") int32 GlyphCount,
    UPARAM(DisplayName = "Text") const FString& Text);

参数与返回值

  • GlyphCount — 文本中字形数量(码点数)
  • Text — 编译时的源文本
  • ReturnFBakedStage(默认阶段烘焙数据,完全 UPROPERTY 构成,Kismet 编译器安全)

重写方法

  1. 动画蓝图编辑器切换 Graph 模式
  2. 事件图中右键 → 覆盖(Override)构建默认动画
  3. 添加 Event BuildDefaultAnimation 节点(携带 GlyphCount / Text 输入)
  4. 使用 Layer / Factory 节点链式编排(见《蓝图节点参考》)
  5. 烘焙 节点输出连接到返回引脚
images/build-default-animation-override.png — 蓝图截图:Graph 模式下覆盖的 Event BuildDefaultAnimation 节点,输入端 GlyphCount/Text,事件图内为构建调度信息 → 创建字形动画层 → 链式微调 → 创建工厂 → 添加层 → 烘焙 → 返回的完整连线 — Blueprint screenshot: overridden Event BuildDefaultAnimation node in Graph mode with GlyphCount/Text inputs, event graph wiring BuildScheduleInfos → CreateLayer → chained tweaks → CreateFactory → AddLayer → Bake → return

使用场景

  • 根据文本长度动态调整错峰节奏(短文本快、长文本慢)
  • 按字形分类差异化调度(跳过空白、标点延迟)
  • 多图层组合(基础层 + 抖动 + 染色)

NOTE

BuildDefaultAnimation 在烘焙时触发一次,运行时不会重复执行。运行时动态调整请使用 设置蓝图变量(触发冷却重烘焙)或控件播放控制。

控件蓝图委托(BlueprintAssignable)

适用场景:在 Widget 蓝图中绑定字形揭示与动画完成事件。

UAnimatedTextBlock

事件签名触发时机
字形揭示(蓝图)int32 RevealedCount每揭示一个字形(累计已揭示数)
动画完成(蓝图)动画播放完成

UAnimatedRichTextBlock

事件签名触发时机
字形揭示(蓝图)int32 CharIndex, FString Character每揭示一个字形(码点索引 + 字符)
动画完成(蓝图)动画播放完成

绑定方式:控件引脚拖出 → Assign 字形揭示(蓝图) → 自定义事件。

控制器 C++ 委托

适用场景:手动路径(C++)监听控制器生命周期。

UTextAnimationStageController 暴露 3 个 C++ 多播委托(非动态委托,蓝图需经控件代理):

委托签名触发时机
OnGlyphRevealed(int32 GlyphIndex, TCHAR Character)字形首次揭示(反向播放位清除可再次广播)
OnStageChanged(EAnimationStage From, EAnimationStage To)阶段切换
OnAnimationComplete()动画完成
Controller->OnStageChanged.AddLambda([](EAnimationStage From, EAnimationStage To)
{
    UE_LOG(LogTexturge, Log, TEXT("Stage: %d%d"), (int32)From, (int32)To);
});

阶段切换流程

Stopped → Play() → Playing
  → Default 阶段推进(TickAnimation → TransitionTo 检测边界)
  → OnStageChanged(From, To) 广播
  → 全部阶段完成 → OnAnimationComplete → Complete

查询与求值

适用场景:C++ 手动路径获取阶段状态与字形状态。

UTextAnimationStageController* Controller = /* 手动创建的控制器 */;
if (Controller)
{
    Controller->TickAnimation(DeltaTime);                    // 推进时钟

    // 单字形求值(返回当前状态)
    FGlyphAnimationState State = Controller->EvaluateGlyph(GlyphIndex);

    // 阶段查询
    EAnimationStage Stage = Controller->GetCurrentStage();
    float StageTime = Controller->GetStageTime();
    int32 Revealed = Controller->GetRevealedGlyphCount();
}

NOTE

控件路径下 GetStageController() 为编辑器预览用 C++ 访问器——蓝图中请使用控件自身的播放控制节点与委托,不要绕过控件直接操作内部控制器。

常用事件驱动场景

适用场景:实现打字音效、对话推进、UI 提示、跳过功能等交互模式。

  1. 打字音效 — 使用 UEventSoundComponent设置字形音效 + 绑定动画器)或绑定 字形揭示(蓝图) 事件,而非每帧 Tick 轮询
  2. 对话推进动画完成(蓝图) 事件触发下一句对话 / 显示”继续”提示
  3. 打字完成计数UAnimatedTextBlockRevealedCount 参数驱动打字机光标 / 进度条
  4. 跳过功能 — 输入事件调用 跳转到结尾,跳过当前打字动画
  5. 按字形触发逻辑UAnimatedRichTextBlockCharIndex + Character 参数实现逐字特效 / 标点停顿

TIP

打字音效场景建议在 字形揭示(蓝图) 事件中触发音效而非每帧 Tick 检测,以减少不必要的性能开销。事件参数(码点索引 + 字符)已包含触发位置信息。

images/event-graph-binding.png — 事件绑定蓝图示例:左侧 Assign 字形揭示(蓝图)连接到自定义事件(读取 RevealedCount 驱动进度条),右侧 Assign 动画完成(蓝图)连接到对话推进逻辑 — Event binding blueprint example: Assign OnCharacterRevealedBP wired to a custom event (RevealedCount driving a progress bar) on the left, Assign OnAnimationCompleteBP wired to dialog advancement on the right