Skip to main content

Setup Guide

Complete installation and configuration guide for ElysPerceptionPlugin.

Prerequisites

  • Unreal Engine 5.6 or later
  • Basic understanding of Unreal Engine components and actors

Installation

1. Install from FAB Marketplace

Download ElysPerceptionPlugin from the FAB Marketplace and install it into your project.

2. Enable the Plugin

  1. Open your project in Unreal Editor
  2. Go to Edit -> Plugins
  3. Search for "Elys Perception Plugin"
  4. Check the box to enable it
  5. Restart the editor when prompted

3. Verify Installation

In the Content Browser, enable "Show Plugin Content" and verify the ElysPerceptionPlugin folder appears.

4. Update Build Configuration (C++ Projects)

Add the module to your .Build.cs file:

PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
"ElysPerceptionPlugin"
});

Quick Start

Blueprint Setup

1. Add Perception Component

Select your PlayerController or Pawn and add ERPPerceptionComponent.

2. Configure Target Pipeline

In component details, expand Perception | Pipelines and add a channel pipeline:

Basic Settings:

  • Channel Id: Target
  • Default Sampling Range: 2000.0

Pipeline Stages:

  1. Sampler (click + to add):

    • Type: ERPSphereOverlapSampler
    • Trace Channel: Visibility
    • Ignore Context Actor: check
  2. Filters:

    • Type: ERPTargetableFilter
  3. Scorers (each entry has Scorer + Weight):

    • Scorer: ERPDistanceScorer (Normalize By Range: check)
    • Weight: 1.0
  4. Resolver:

    • Type: ERPResolverBase (default: lowest score wins)

Note: The Aggregator is optional. If not set, the pipeline sums the weighted scores automatically.

3. Add Targeting Domain Component

On your PlayerController or Pawn:

  1. Add Component -> ERPTargetingComponent
  2. Set Channel Id to Target
  3. It will auto-find the PerceptionComponent on the same actor

4. Make Actors Targetable

On target actors (enemies, NPCs):

  1. Class Settings -> Interfaces -> Add ERPTargetable
  2. In Event Graph, implement Can Be Targeted By
  3. Return true (or add custom logic)

5. Bind Events

On your targeting component:

Event BeginPlay
-> Get Component (ERPTargetingComponent)
-> Bind Event to OnDomainCandidateChanged
-> Print String: "Target Changed: {NewCandidate}"

Or use UERPChannelListenerComponent for lightweight event-only listening:

1. Add Component -> ERPChannelListenerComponent
2. Set Channel Id to "Target"
3. Bind to OnCandidateAcquired / OnCandidateLost

Blueprint Example

Complete Target System

Variables:

  • CurrentTarget (Actor reference)

Event Graph:

// Using TargetingComponent events
Event: OnDomainCandidateChanged (Previous, New, ChannelId)
-> Set CurrentTarget = New
-> Branch: IsValid(New)
True: -> Print "Target Acquired"
False: -> Print "Target Lost"

// Get current target on demand
Event Input: AttackButton
-> TargetingComp -> GetCurrentCandidate
-> IsValid?
True: -> Execute attack on target
False: -> Print: "No target available"

C++ Setup

1. Create Component

YourPlayerController.h:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "Core/ERPPerceptionComponent.h"
#include "Domains/Targeting/ERPTargetingComponent.h"
#include "YourPlayerController.generated.h"

UCLASS()
class YOURPROJECT_API AYourPlayerController : public APlayerController
{
GENERATED_BODY()

public:
AYourPlayerController();

protected:
virtual void BeginPlay() override;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Perception")
UERPPerceptionComponent* PerceptionComponent;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Perception")
UERPTargetingComponent* TargetingComponent;

private:
UFUNCTION()
void OnTargetChanged(AActor* Previous, AActor* New, FName ChannelId);
};

YourPlayerController.cpp:

#include "YourPlayerController.h"

AYourPlayerController::AYourPlayerController()
{
PerceptionComponent = CreateDefaultSubobject<UERPPerceptionComponent>(TEXT("PerceptionComponent"));

TargetingComponent = CreateDefaultSubobject<UERPTargetingComponent>(TEXT("TargetingComponent"));
TargetingComponent->ChannelId = FName("Target");
}

void AYourPlayerController::BeginPlay()
{
Super::BeginPlay();

// TargetingComponent auto-binds to PerceptionComponent at BeginPlay
TargetingComponent->OnDomainCandidateChanged.AddDynamic(this, &AYourPlayerController::OnTargetChanged);
}

void AYourPlayerController::OnTargetChanged(AActor* Previous, AActor* New, FName ChannelId)
{
if (New)
{
UE_LOG(LogTemp, Log, TEXT("Target acquired: %s"), *New->GetName());
}
else
{
UE_LOG(LogTemp, Log, TEXT("Target lost"));
}
}

2. Implement Targetable Interface

YourEnemy.h:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Domains/Targeting/ERPTargetable.h"
#include "YourEnemy.generated.h"

UCLASS()
class YOURPROJECT_API AYourEnemy : public ACharacter, public IERPTargetable
{
GENERATED_BODY()

public:
virtual bool CanBeTargetedBy_Implementation(AActor* TargetingActor) const override;

protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat")
bool bIsAlive = true;
};

YourEnemy.cpp:

#include "YourEnemy.h"

bool AYourEnemy::CanBeTargetedBy_Implementation(AActor* TargetingActor) const
{
return bIsAlive;
}

Testing

Verification Checklist

  • Perception component added to PlayerController/Pawn
  • Pipeline configured with all required stages (Sampler + Resolver minimum)
  • Default sampling range set (e.g., 2000)
  • Domain component added (TargetingComponent or InteractionComponent)
  • Channel Id matches between pipeline and domain component
  • Target actors implement appropriate interface (IERPTargetable or IERPInteractable)
  • Interface methods return expected values
  • Events bound and firing

Debug Visualization

Enable bDebugPerception on ERPPerceptionComponent to see candidate logging.

Console commands:

stat GAME  // Show component tick times

Performance Tuning

  • PerceptionTickInterval: Set on ERPPerceptionComponent to reduce evaluation frequency (e.g., 0.1 = 10 Hz)
  • DefaultSamplingRange: Keep as low as practical
  • Scorer Weights: Use to balance multiple scoring factors

Troubleshooting

Target Not Detected

Check Interface: Verify target implements IERPTargetable and CanBeTargetedBy returns true.

Check Range: Increase DefaultSamplingRange or verify actors are within range.

Check Collision: Verify TraceChannel in Sampler matches actor collision settings.

Events Not Firing

Bind Timing: Bind in BeginPlay, not constructor. Use AddDynamic for delegates.

Check Channel Id: Verify ChannelId matches between pipeline configuration and domain component.

Performance Issues

Reduce Range: Lower DefaultSamplingRange to minimum needed.

Adjust Tick Rate: Set PerceptionTickInterval on the perception component (e.g., 0.1 for 10 Hz).

Optimize Sampler: Use tighter Actor Class filter.


Next Steps

Read Pipeline System to understand how detection works.

Explore Interaction Guide for proximity-based interactions.

Explore Targeting Guide for combat targeting.

Check API Reference for detailed class documentation.