the API revolves around the
UE::DataValidation::IFixer
type. fixers are pieces of code that can fix your issues given their application conditions are metonce you have a fixer, you can display it in your (
FTokenizedMessage
-based) validation messages usingFFixToken
minimal example:
auto Message = FTokenizedMessage::Create( EMessageVerbosity::Error, LOCTEXT( "FoundNoneEntries", "Found None entries in ability array." "Please remove them, otherwise they may cause crashes during runtime." ) ); Message->AddToken( UE::DataValidation::MakeFix( [this] { Abilities.SetNum(Algo::RemoveIf( Abilities, [](const UGameplayAbility* Ability) { return Ability == nullptr; } )); return FFixResult::Success(LOCTEXT("NoneEntriesRemoved", "None entries have been removed")); } ) ->CreateToken(LOCTEXT("RemoveNoneEntries", "Remove the None entries")) ); Context.AddMessage(MoveTemp(Message));
fixers can be freely stacked and composed - there are a few such layers available out of the box in the engine
UE::DataValidation::FMutuallyExclusiveFixSet
is actually not a fixer, but a fixer builder - you give it a set of fixers, and it will make it so that when one is applied, it becomesEFixApplicability::Applied
, and the rest becomesEFixApplicability::DidNotApply
- thus creating a set of mutually-exclusive fixes