编辑器定制化
Texturge 编辑器通过 IDetailCustomization、IPropertyTypeCustomization、FKismetCompilerContext 扩展与模板化参数帮助器实现深度定制。
FAnimatedTextBlockDetails
为 UAnimatedTextBlock 控件提供自定义细节(Details)面板(IDetailCustomization)。
class FAnimatedTextBlockDetails : public IDetailCustomization
{
static TSharedRef<IDetailCustomization> MakeInstance();
void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override;
private:
void BuildParameterRows(IDetailCategoryBuilder& AnimCat,
IDetailLayoutBuilder& DetailBuilder,
UAnimatedTextBlock* Widget,
TSharedPtr<IPropertyHandle> OverridesHandle);
void SaveAllCDODefaults(UTextAnimInstance* CDO);
UTextAnimInstance* GetTargetCDO() const;
static bool IsUserParameter(FProperty* Prop);
TWeakObjectPtr<UAnimatedTextBlock> TargetWidget;
TMap<FName, TArray<uint8>> CDODefaultsForReset;
};
参数行生成机制
- 通过
AddExternalObjectProperty将UAnimParameterOverrides的 6 组覆盖 Map 作为外部对象属性挂入细节面板 - 枚举关联
UTextAnimationBlueprint生成的UTextAnimInstanceCDO 上的全部属性,筛出IsUserParameter(CPF_BlueprintVisible且非系统属性)的蓝图变量 - 为每个蓝图变量生成一行:变量名 + 覆盖值输入框 + 重置(Reset)按钮
SaveAllCDODefaults在面板打开时缓存 CDO 默认值,Reset 通过AnimParamReset<UAnimParameterOverrides>模板移除覆盖项并回写 CDO 副本
NOTE
CDO 副本方案:面板编辑的是
UTextAnimInstanceCDO 的副本,引擎原生编辑器行为,蓝图 CDO 永不修改。烘焙时经FAnimInstanceCustomizer注入烘焙临时实例。
FTextAnimationInstanceDetails
为 UTextAnimInstance 提供自定义细节(Details)面板(IDetailCustomization),仅控制分类排序,不修改属性布局。
class FTextAnimationInstanceDetails : public IDetailCustomization
{
static TSharedRef<IDetailCustomization> MakeInstance();
void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override;
};
FAnimationEntryDetails
为 FAnimationEntry 结构体提供自定义 Details(IPropertyTypeCustomization),在 UTextAnimationDataAsset 的 Entries 数组中生效。
class FAnimationEntryDetails : public IPropertyTypeCustomization
{
static TSharedRef<IPropertyTypeCustomization> MakeInstance();
void CustomizeHeader(TSharedRef<IPropertyHandle> PropertyHandle,
FDetailWidgetRow& HeaderRow,
IPropertyTypeCustomizationUtils& CustomizationUtils) override;
void CustomizeChildren(TSharedRef<IPropertyHandle> PropertyHandle,
IDetailChildrenBuilder& ChildBuilder,
IPropertyTypeCustomizationUtils& CustomizationUtils) override;
private:
TMap<FName, TArray<uint8>> CDODefaults;
};
与控件面板相同,条目级参数覆盖(6 组 Map)也通过 CDO 副本 + Reset 机制编辑,底层复用 TAnimParamTraits<T, FAnimationEntry> 特化。
UTextAnimationTrackProxy
细节面板编辑轨道属性的代理对象(UObject),将 FTextAnimationTrack 包装为可编辑属性:
UCLASS(meta = (DisplayName = "文本动画轨道代理"))
class UTextAnimationTrackProxy : public UObject
{
UPROPERTY(EditAnywhere, Category = "轨道", meta = (DisplayName = "轨道属性"))
FTextAnimationTrack Track;
};
FTextAnimationBlueprintCompilerContext
Kismet 编译器扩展,负责将 UTextAnimationBlueprint 编译为 UTextAnimationBlueprintGeneratedClass。
class FTextAnimationBlueprintCompilerContext : public FKismetCompilerContext
{
// FKismetCompilerContext 覆写
virtual void SpawnNewClass(const FString& NewClassName) override;
virtual void CleanAndSanitizeClass(UBlueprintGeneratedClass* ClassToClean, UObject*& InOutOldCDO) override;
virtual void EnsureProperGeneratedClass(UClass*& InOutTargetClass) override;
virtual void CreateClassVariablesFromBlueprint() override;
virtual void CreateFunctionList() override;
virtual void FinishCompilingClass(UClass* Class) override;
virtual bool ValidateGeneratedClass(UBlueprintGeneratedClass* Class) override;
virtual void PreCompile() override;
private:
void ValidateTrackData(); // 轨道数据完整性校验(5 条规则)
FGuid FixupVariableGUIDs(UTextAnimationBlueprint*, const FName&);
void CopyAssetDataToClass(UTextAnimationBlueprintGeneratedClass* OutClass);
};
编译流水线
| 步骤 | 覆写 | 行为 |
|---|---|---|
| 1 | PreCompile | 编译前准备 |
| 2 | CreateClassVariablesFromBlueprint | 基类扫描前确保注入变量(2026-07 重构修正:变量注入提前到基类调用之前) |
| 3 | FixupVariableGUIDs | 为蓝图变量维护稳定 GUID(查 VariableNameToGuidMap,未找到则按路径名生成确定性 GUID 并写回) |
| 4 | ValidateTrackData | 校验 Tracks 数组完整性(5 条规则) |
| 5 | FinishCompilingClass | CopyAssetDataToClass 复制 Tracks 等资产数据,计算 CompiledTotalDuration = max(StartTime + Duration) |
| 6 | CompileCount | 每次编译递增,参与蓝图指纹哈希,保证编译后缓存失效 |
编译输出写入 UTextAnimationBlueprintGeneratedClass(CompiledTracks / CompiledFrameRate / CompiledTotalDuration / CompiledCharacterInterval)。
模板化参数帮助器
AnimParamTraitsHelpers.h(Editor 模块,header-only)提供 3 个共享模板函数:
| 模板 | 说明 |
|---|---|
AnimParamNeedsReset<Owner>(Ovr, PropName, EAnimParamType, DefVal) | 判断当前覆盖值是否偏离 CDO 默认值(决定重置按钮显示) |
AnimParamReset<Owner>(Ovr, CDOCopy, PropName, Prop, EAnimParamType, DefVal) | 移除覆盖项并恢复 CDO 副本默认值 |
AnimParamSync<Owner>(Ovr, CDOCopy, PropName, EAnimParamType) | 将 CDO 副本属性值同步写入覆盖 Map |
底层映射由运行时模块的 TAnimParamTraits<T, Owner> 特化(AnimatedTextBlock.h 的 DECLARE_ANIM_PARAM_TRAIT 与 AnimationEntry.h 的 DECLARE_ENTRY_TRAIT)提供。
扩展自定义 Detail 面板
插件支持注册外部自定义细节面板,步骤:
- 创建继承
IDetailCustomization的类,实现CustomizeDetails(IDetailLayoutBuilder&) - 在模块的
StartupModule()中注册:
FPropertyEditorModule& PropertyModule =
FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyModule.RegisterCustomClassLayout(
UYourClass::StaticClass()->GetFName(),
FOnGetDetailCustomizationInstance::CreateStatic(&FYourDetails::MakeInstance));
- 在
ShutdownModule()中调用UnregisterCustomClassLayout取消注册
所有内置细节自定义均通过相同机制绑定,确保与引擎细节面板标准化。