Skip to main content

Route Behavior By Interactable Tag

Type: Plugin/Engine only

This example keeps a single actor class but routes the behavior using FEDInteractionEventContext::InteractableTag.

Example

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Data/EDInteractionTypes.h"
#include "MyTaggedInteractableActor.generated.h"

class UArrowComponent;
class UEDInteractableComponent;
class USceneComponent;
class UStaticMeshComponent;

UCLASS()
class AMyTaggedInteractableActor : public AActor
{
GENERATED_BODY()

public:
AMyTaggedInteractableActor();

protected:
virtual void BeginPlay() override;

UPROPERTY(VisibleAnywhere)
TObjectPtr<USceneComponent> Root;

UPROPERTY(VisibleAnywhere)
TObjectPtr<UStaticMeshComponent> VisualMesh;

UPROPERTY(VisibleAnywhere)
TObjectPtr<USceneComponent> WidgetHolder;

UPROPERTY(VisibleAnywhere)
TObjectPtr<UArrowComponent> CenterArrow;

UPROPERTY(VisibleAnywhere)
TObjectPtr<UEDInteractableComponent> InteractableComponent;

UFUNCTION()
void HandleInteractionSuccessful(const FEDInteractionEventContext& Context);
};
#include "MyTaggedInteractableActor.h"

#include "Components/ArrowComponent.h"
#include "Components/EDInteractableComponent.h"
#include "Components/SceneComponent.h"
#include "Components/StaticMeshComponent.h"
#include "GameplayTagContainer.h"

AMyTaggedInteractableActor::AMyTaggedInteractableActor()
{
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
SetRootComponent(Root);

VisualMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualMesh"));
VisualMesh->SetupAttachment(Root);
VisualMesh->ComponentTags.Add(FName(TEXT("DimensionComponent")));

WidgetHolder = CreateDefaultSubobject<USceneComponent>(TEXT("WidgetHolder"));
WidgetHolder->SetupAttachment(Root);
WidgetHolder->ComponentTags.Add(FName(TEXT("WidgetHolderComponent")));

CenterArrow = CreateDefaultSubobject<UArrowComponent>(TEXT("CenterArrow"));
CenterArrow->SetupAttachment(VisualMesh);
CenterArrow->ComponentTags.Add(FName(TEXT("CenterComponent")));

InteractableComponent = CreateDefaultSubobject<UEDInteractableComponent>(TEXT("InteractableComponent"));
}

void AMyTaggedInteractableActor::BeginPlay()
{
Super::BeginPlay();
InteractableComponent->OnInteractionSuccessful.AddDynamic(this, &AMyTaggedInteractableActor::HandleInteractionSuccessful);
}

void AMyTaggedInteractableActor::HandleInteractionSuccessful(const FEDInteractionEventContext& Context)
{
const FGameplayTag LootTag = FGameplayTag::RequestGameplayTag(TEXT("Interactable.Loot"), false);
const FGameplayTag DoorTag = FGameplayTag::RequestGameplayTag(TEXT("Interactable.Door"), false);
const FGameplayTag SavePointTag = FGameplayTag::RequestGameplayTag(TEXT("Interactable.SavePoint"), false);

if (LootTag.IsValid() && Context.InteractableTag.MatchesTagExact(LootTag))
{
UE_LOG(LogTemp, Log, TEXT("Handle loot behavior"));
return;
}

if (DoorTag.IsValid() && Context.InteractableTag.MatchesTagExact(DoorTag))
{
UE_LOG(LogTemp, Log, TEXT("Handle door behavior"));
return;
}

if (SavePointTag.IsValid() && Context.InteractableTag.MatchesTagExact(SavePointTag))
{
UE_LOG(LogTemp, Log, TEXT("Handle save point behavior"));
}
}

Note

This example assumes those gameplay tags exist in your project settings. The routing API itself is valid Unreal/plugin API.