蓝图事件参考

Texturge 通过两层事件机制连接蓝图:BlueprintAssignable 委托(在事件图表中直接绑定)与 BlueprintNativeEvent(在动画蓝图中覆盖实现)。

控件蓝图委托

UAnimatedTextBlock

委托签名DisplayName触发时机
OnCharacterRevealedBPFOnAnimTextCharRevealedBP(int32 RevealedCount)字形揭示(蓝图)每揭示一个字形(参数为累计已揭示数)
OnAnimationCompleteBPFOnAnimTextAnimationCompleteBP动画完成(蓝图)动画播放完成
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAnimTextCharRevealedBP, int32, RevealedCount);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnAnimTextAnimationCompleteBP);

UPROPERTY(BlueprintAssignable, Category = "Animation", meta = (DisplayName = "字形揭示(蓝图)"))
FOnAnimTextCharRevealedBP OnCharacterRevealedBP;

UPROPERTY(BlueprintAssignable, Category = "Animation", meta = (DisplayName = "动画完成(蓝图)"))
FOnAnimTextAnimationCompleteBP OnAnimationCompleteBP;

UAnimatedRichTextBlock

委托签名DisplayName触发时机
OnCharacterRevealedBPFOnCharacterRevealedBP(int32 CharIndex, FString Character)字形揭示(蓝图)每揭示一个字形(码点索引 + 字符)
OnAnimationCompleteBPFOnAnimatedRichTextAnimationCompleteBP动画完成(蓝图)动画播放完成
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnCharacterRevealedBP, int32, CharIndex, FString, Character);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnAnimatedRichTextAnimationCompleteBP);

蓝图绑定步骤

  1. 在事件图表中获取控件引用(UAnimatedTextBlock / UAnimatedRichTextBlock
  2. 从控件引脚拖出 → 搜索 Assign 字形揭示(蓝图)Assign 动画完成(蓝图)
  3. 连接红色事件引脚到自定义事件节点
  4. 在自定义事件中读取输出参数

Blueprint 接线示例

[AnimatedTextBlock Ref]
    ├── [Assign OnCharacterRevealedBP] ──→ [Custom Event: OnCharRevealed (RevealedCount)]
    │       → [Print String "Revealed {RevealedCount}"]

    └── [Assign OnAnimationCompleteBP] ──→ [Custom Event: OnDone]
            → [下一句对话 / 解锁 UI]

控制器 C++ 委托

UTextAnimationStageController 暴露 3 个 C++ 多播委托(非动态委托,蓝图不可直接绑定,需经控件代理或 C++ 绑定):

委托签名触发时机
OnGlyphRevealedFOnGlyphRevealed(int32 GlyphIndex, TCHAR Character)字形首次揭示;反向播放时位清除可再次广播
OnStageChangedFOnStageChanged(EAnimationStage From, EAnimationStage To)阶段切换
OnAnimationCompleteFOnAnimationComplete动画完成

C++ 绑定示例:

Controller->OnStageChanged.AddLambda([](EAnimationStage From, EAnimationStage To)
{
    UE_LOG(LogTexturge, Log, TEXT("Stage: %d%d"), (int32)From, (int32)To);
});

BuildDefaultAnimation(BlueprintNativeEvent)

UTextAnimInstance 中最核心的蓝图事件——设计师在动画蓝图(Graph 模式)中覆盖它,自定义默认阶段的完整动画逻辑。

UFUNCTION(BlueprintNativeEvent,
    meta = (DisplayName = "构建默认动画",
        ToolTip = "构建默认动画阶段(可在蓝图中覆盖)",
        ReturnDisplayName = "Baked Stage"))
FBakedStage BuildDefaultAnimation(
    UPARAM(DisplayName = "Glyph Count") int32 GlyphCount,
    UPARAM(DisplayName = "Text") const FString& Text);
参数类型说明
GlyphCountint32文本中字形数量
Textconst FString&源文本
ReturnFBakedStage默认阶段的烘焙数据(完全 UPROPERTY 构成,Kismet 编译器安全)

蓝图覆盖示例

  1. 在动画蓝图 Graph 模式中:右键图表 → Override构建默认动画
  2. 添加 Event BuildDefaultAnimation 节点(自动携带 GlyphCount / Text 输入)
  3. 使用 构建调度信息 节点生成 FGlyphScheduleInfo 数组
  4. 使用 创建字形动画层 → 调度 / 微调节点 → 创建工厂添加层烘焙 链式编排
  5. 烘焙 节点输出 FBakedStage 连接到返回引脚

蓝图编排示例

[Event BuildDefaultAnimation (GlyphCount, Text)]
    → [构建调度信息 (Text)] → Schedule
    → [创建字形动画层 (GlyphAnimations[0], Override, Schedule)] → Layer
        → [设置字形延迟 (Layer, -1, 0.05)]
        → [跳过字形 (Layer, -1)]  ← 跳过空白
        → [乘算字形缩放 (Layer, 0, (1.2, 1.2))]
    → [创建工厂 (Layer, Schedule)] → Factory
        → [乘算字形平移 (Factory, -1, (2.0, 1.0))]
    → [烘焙 (Factory)] → Return Baked Stage

默认 _Implementation

C++ 默认实现通过 Layer / Factory 管线烘焙:

FBakedStage UTextAnimInstance::BuildDefaultAnimation_Implementation(int32 GlyphCount, const FString& Text)
{
    TArray<FGlyphScheduleInfo> Schedule = BuildScheduleInfos(Text);
    UGlyphAnimationLayer* BaseLayer = CreateLayer(GlyphAnimations[0], Override, Schedule);
    UGlyphAnimationFactory* Factory = CreateFactory(BaseLayer, Schedule);
    for (int32 i = 1; i < GlyphAnimations.Num(); ++i)
    {
        Factory->AddLayer(CreateLayer(GlyphAnimations[i], Additive, Schedule));
    }
    return Factory->Bake();
}

NOTE

若蓝图覆盖返回无效结果,FAnimationCompiler::BakeAllStages 自动回退到 _Implementation

蓝图变量即参数

动画蓝图不预设任何 C++ 参数。设计师在类默认值(Class Defaults)中自行声明变量,在 BuildDefaultAnimation 事件中读取并配置调度:

  • 变量类型支持:float / int32 / bool / FVector / FLinearColor / FVector2D
  • 运行时通过 设置蓝图变量 系列节点动态修改,标记 Dirty 后经冷却(MinFramesBetweenRebakes = 3)自动重烘焙

生命周期与事件接线最佳实践

TIP

控件事件(OnCharacterRevealedBP / OnAnimationCompleteBP)由控件自动绑定到控制器内部委托——无需手动管理控制器生命周期;手动创建控制器时,请在 Initialize 之后再绑定 C++ 委托。

  1. 事件绑定放在初始化之后:手动路径中 Initialize 完成后配置委托,避免空引用
  2. 利用参数区分字形:富文本路径的 OnCharacterRevealedBP 提供 CharIndex + Character,可用于逐字音效/打字机光标
  3. 在 OnAnimationCompleteBP 中驱动游戏逻辑:全部动画结束后释放资源、推进对话或解锁 UI
  4. 覆盖 BuildDefaultAnimation 时保持链式返回烘焙 节点输出直接连接到事件返回引脚,不要额外封装
  5. 运行时参数用 SetBlueprintVariable:在 播放 前调用,避免动画中途重烘焙抖动
images/blueprint-events.png — 蓝图事件接线图:左侧为 BuildDefaultAnimation 覆盖事件图(构建调度信息 → 创建字形动画层 → 链式微调 → 创建工厂 → 烘焙 → 返回),右侧为控件事件绑定(Assign OnCharacterRevealedBP 与 Assign OnAnimationCompleteBP 连接到自定义事件) — Blueprint event wiring diagram: left shows BuildDefaultAnimation override event graph (BuildScheduleInfos → CreateLayer → chained tweaks → CreateFactory → Bake → return), right shows widget event binding (Assign OnCharacterRevealedBP and Assign OnAnimationCompleteBP to custom events)