Validation In C++
You have two main C++ extension paths.
Option 1: Subclass UEDInteractionConditionValidator
This is the best option for reusable rules that can be assigned in multiple places.
Example: Require a pawn tag
#pragma once
#include "CoreMinimal.h"
#include "Validation/EDInteractionConditionValidator.h"
#include "MyRequirePawnTagValidator.generated.h"
UCLASS(BlueprintType, EditInlineNew, DefaultToInstanced)
class UMyRequirePawnTagValidator : public UEDInteractionConditionValidator
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Validation")
FName RequiredTag = TEXT("CanInteract");
virtual void ValidateInteraction_Implementation(const FEDInteractionValidationContext& Context, FEDInteractionValidationResult& InOutResult) override;
};
#include "MyRequirePawnTagValidator.h"
#include "GameFramework/Pawn.h"
void UMyRequirePawnTagValidator::ValidateInteraction_Implementation(const FEDInteractionValidationContext& Context, FEDInteractionValidationResult& InOutResult)
{
Super::ValidateInteraction_Implementation(Context, InOutResult);
if (!InOutResult.bAllowInteraction)
{
return;
}
if (!IsValid(Context.InstigatorPawn) || !Context.InstigatorPawn->ActorHasTag(RequiredTag))
{
InOutResult.bAllowInteraction = false;
InOutResult.DenyReason = EEDInteractionDenyReason::SpecialCondition;
InOutResult.FailureMessage = FText::FromString(TEXT("Missing required pawn tag."));
}
}
Assign this validator in:
GlobalInteractionValidatorsValidationRulesValidationRuleClassesfor foliage
Option 2: Override the player component hook
Subclass UEDPlayerInteractionComponent and override:
ValidateInteractionSpecialConditions_Implementation(...)
This is useful for centralized rules.
void UMyPlayerInteractionComponent::ValidateInteractionSpecialConditions_Implementation(
const FEDInteractionValidationContext& Context,
FEDInteractionValidationResult& InOutResult)
{
Super::ValidateInteractionSpecialConditions_Implementation(Context, InOutResult);
if (!InOutResult.bAllowInteraction)
{
return;
}
if (bDisableAllSpecialInteractions)
{
InOutResult.bAllowInteraction = false;
InOutResult.DenyReason = EEDInteractionDenyReason::SpecialCondition;
InOutResult.FailureMessage = FText::FromString(TEXT("Interactions are currently disabled."));
}
}
Choosing between both approaches
Prefer a validator object when:
- you want reuse
- you want designers to assign/tune rules
- the same rule applies to actors and foliage
Prefer the player component override when:
- the rule is highly project-specific
- it depends on player/controller state
- you want one centralized decision point
Foliage support
The validation API is not actor-only.
When the target is foliage, FEDInteractionValidationContext includes:
bIsFoliageInstance = trueFoliageInstanceComponentFoliageInstanceTransformInteractionLocationbHasFoliageDataFoliageData
That makes it practical to implement tool checks, progression checks, or harvesting rules for foliage instances.