多图层动画设置
Texturge 的多图层系统允许每个字形拥有多组独立的动画曲线数据(FPerLayerCurves),各层按指定的 ETextAnimationBlendMode 组合为最终的字形动画状态。
NOTE
Texturge 不存在 SDF 阈值与像素图层的概念。多图层是对 21 通道曲线数据的多层叠加与混合(Override / Additive / Multiply / CrossFade)。
核心概念
- 每个
FBakedGlyph内部存储TArray<FPerLayerCurves> LayerCurves——该字形各图层的曲线数据(LayerCurves[0]最底层 →LayerCurves[N-1]最顶层) FBakedGlyph::Evaluate()从FGlyphAnimationState::Identity()开始逐层求值,按各层BlendMode组合;空通道跳过,保留已有值- 层间互不影响:每层拥有
UGlyphAnimation曲线的深拷贝副本(ExtractCurves在创建时生成),多层共用同一资产不会互相干扰
创建图层资产
UGlyphAnimationLayer 通过静态工厂创建(必须传入动画资产与混合模式):
// 从调度数组创建
TArray<FGlyphScheduleInfo> Schedule = FAnimationCompiler::BuildScheduleInfos(Text);
UGlyphAnimationLayer* Layer = UGlyphAnimationLayer::CreateLayer(
AnimAsset, // UGlyphAnimation*
ETextAnimationBlendMode::Override, // 混合模式(基础层常用 Override)
Schedule, // 调度数组
EPlayMode::Forward, // 播放方向(默认)
1.0f, // 播放倍速(默认)
1 // 循环次数(默认;0 = 无限)
);
// 或从文本创建(自动构建调度)
UGlyphAnimationLayer* LayerFromText = UGlyphAnimationLayer::CreateLayerFromText(
AnimAsset, Text, ETextAnimationBlendMode::Additive);
配置图层
播放模式
Layer->SetPlayMode(EPlayMode::PingPong); // 播放方向
Layer->SetPlayMode(EPlayMode::Forward, 2.0f, 3); // 方向 + 倍速 + 循环次数
NOTE
EPlayMode只有 Forward / Reverse / PingPong。循环由第三个参数NumberOfLoops控制(0 = 无限循环)。
调度(Index = -1 作用于全部)
Layer->SetStartDelayAt(-1, 0.0f); // 绝对起始延迟
Layer->SetDelayAt(-1, 0.05f); // 逐字形错峰(第 i 个字形 = 0 + i × 0.05)
Layer->SkipAt(-1); // 跳过全部(再按分类恢复)
Layer->SetSkipAnimationAt(3, false); // 恢复第 3 个字形
Layer->SetAnimationClipAt(0.1f, 0.2f); // 前端裁剪 0.1s、末端裁剪 0.2s
字形微调(有序操作步骤)
10 属性 × 5 操作(乘算 / 除算 / 加算 / 减算 / 清除步骤)+ 清除全部:
Layer->MultiplyScaleAt(0, FVector2D(1.2f, 1.2f)); // 第 0 字形缩放 ×1.2
Layer->AddRotationAt(-1, 15.0f); // 全部字形旋转 +15°
Layer->SubtractOpacityAt(2, 0.1f); // 第 2 字形不透明度 -0.1
Layer->ClearGlyphOverridesAt(0); // 清空第 0 字形全部步骤
组装工厂
UGlyphAnimationFactory 管理所有图层并执行合并烘焙:
// 1. 创建工厂(需要基础层 + 全局调度)
UGlyphAnimationFactory* Factory = UGlyphAnimationFactory::CreateFactory(BaseLayer, Schedule);
// 或从文本创建
UGlyphAnimationFactory* FactoryFromText = UGlyphAnimationFactory::CreateFactoryFromText(BaseLayer, Text);
// 2. 按顺序添加图层(后添加的层级更高,叠加在更上方)
Factory->AddLayer(PositionLayer);
Factory->AddLayer(ColorAnimLayer);
Factory->AddLayer(ShadowLayer);
// 3. 执行烘焙(返回 FBakedStage)
FBakedStage Stage = Factory->Bake();
在 BuildDefaultAnimation 中组合
BuildDefaultAnimation 是实现多图层逻辑的标准位置。C++ 默认实现即完整封装了创建 → 配置 → 烘焙流程:
FBakedStage UTextAnimInstance::BuildDefaultAnimation_Implementation(
int32 GlyphCount, const FString& Text)
{
TArray<FGlyphScheduleInfo> Schedule = BuildScheduleInfos(Text);
// 基础层:Override
UGlyphAnimationLayer* BaseLayer = CreateLayer(GlyphAnimations[0], ETextAnimationBlendMode::Override, Schedule);
BaseLayer->SetDelayAt(-1, 0.05f); // 逐字错峰
BaseLayer->SkipAt(-1); // 配合分类恢复(跳过空白)
// 叠加层:Additive
UGlyphAnimationFactory* Factory = CreateFactory(BaseLayer, Schedule);
for (int32 i = 1; i < GlyphAnimations.Num(); ++i)
{
UGlyphAnimationLayer* Layer = CreateLayer(GlyphAnimations[i], ETextAnimationBlendMode::Additive, Schedule);
Factory->AddLayer(Layer);
}
// 工厂级微调(作用于混合后的最终状态)
Factory->MultiplyTranslationAt(-1, FVector2D(2.0f, 1.0f));
return Factory->Bake();
}
数据最终形态
烘焙后,每个 FBakedGlyph 包含:
FBakedGlyph
├── LayerCurves[0]: FPerLayerCurves(21 通道)+ BlendMode::Override
├── LayerCurves[1]: FPerLayerCurves(21 通道)+ BlendMode::Additive
├── LayerCurves[2]: FPerLayerCurves(21 通道)+ BlendMode::Multiply
└── FactoryOverride: FGlyphCurveOverride(工厂级微调,求值时整体应用一次)
运行时 FBakedGlyph::Evaluate() 按索引顺序逐层求值并组合;FactoryOverride 在全部层混合后的最终状态上整体应用一次(非逐层叠加),静态字形(bIsStatic)不应用。