Skip to content
Connecting DocsDocumentation
Main website

Connecting Docs

Pixel Era

Version 3.6.0

Read a texture or render target

1. Add the manager

Place Pixel Era Manager in the level. Add a variable of that object-reference type to your Blueprint, make it Instance Editable, and assign the placed manager. The node screenshots call this variable Reader.
Pixel Era Manager placed in the level and assigned to a Blueprint
  1. Manager reference
    Assign the actor you placed in this level.

2. Prepare the source

For a Texture2D, enable Never Stream and disable Virtual Texture Streaming. Keep your usual compression. A render target needs neither preparation setting.
Texture settings with Never Stream enabled and Virtual Texture Streaming disabled
  1. Virtual Texture Streaming: off
  2. Never Stream: on

3. Create the request

On BeginPlay, call Read Texture Request. Set Key to PlayerGround, choose your Source, and set UV between 0 and 1. RGBA8 is the default; use RGBA16F for HDR or negative values.
Read Texture Request feeding Get Pixel Value through the same key
  1. One key per sample
    Use a unique key for every simultaneous sample.
  2. Choose a UV
    0.5, 0.5 reads the centre.

4. Use the latest color

On Tick, call Get Pixel Value with the same key and manager. Branch on Available; use Color from the true path.
Get Pixel Value: Available connected to a Branch
  1. Wait for Available
    A new request has no completed result yet.

5. Update and remove

Submit the same key when the UV changes. The registered source keeps refreshing. Call Remove Sample when finished, including EndPlay. Each simultaneous sample needs its own key.
EndPlay connected to Remove Sample
  1. Remove the same key
    Call this when finished, including EndPlay.

Read a material

1. Prepare the material

Open a Surface material. Add Pixel Era: Sample Output and connect the color you want to RGB. Connect Alpha if needed; otherwise it returns 1. Apply the material and let it compile.
Material color connected to the Sample Output RGB input
  1. Connect the color to RGB
    Alpha is optional; leaving it empty returns 1.

2. Request the color

Place Pixel Era Manager and keep its reference, as in Read a texture. Call Request Material Read with Key = MaterialProbe, your material or material instance, UV, and Precision.
Request Material Read with manager, material, key, UV and precision
  1. Material or instance
    Use the prepared material or one of its instances.

3. Use the result

Call Get Pixel Value with MaterialProbe and the same manager. Use Color when Available is true. Update the request when UV changes. Remove MaterialProbe when finished, as in Read a texture.
Material request result and removal graphs
  1. Check Available
    Use Color on the true path.

Map your world

1. Place the area

Add Pixel Era Play Area. Choose XY or YZ and Field Size / cm. Move the plane to your minimum depth, then click New Asset.
Play Area settings, orientation, size and New Asset
  1. Create the asset
    New Asset creates and assigns the field asset.
  2. Choose XY or YZ
    Field Size sets the footprint in centimetres.

2. Choose the source

Open the Heightfield Asset and name its row Hazard. Choose Texture and assign Map, or Render Target and assign its input. For painted volumes without a color map, choose Heightfield Only. Prepare Texture2D sources as shown in Read a texture.
Heightfield source selection and channel settings
  1. Choose the source
    Assign the matching texture or render target input below.

3. Set depth limits if needed

For textures or render targets, Depth Routing links color channels to heightfield channels. Leave None for a flat map. Capture or paint any depth channel you use. Heightfield Only returns 1 inside enabled intervals, 0 outside.
Color channels routed to optional depth channels
  1. Choose a depth channel
    Several source channels can share the same painted depth. None leaves that channel ungated.

4. Add the receiver

Add PixelEra_WorldMapper to your actor. It finds the Play Areas automatically. Use World Offset to move the sampling point.
WorldMapper component settings
  1. Sampling offset
    Relative to the actor location.
  2. Tick Only If Moved
    Enable for static fields. Leave off to react to animated fields while stationary.

5. Handle horizontal results

Select WorldMapper. Under Events, click + for On XY Pixel Color Updated. Connect Row to Switch on Name, add Hazard, and use Color.
WorldMapper XY event with Switch on Name
  1. Horizontal event
    Add Hazard to Switch on Name.

For vertical areas

Use On YZ Pixel Color Updated instead.
WorldMapper YZ event with Switch on Name
  1. Vertical event
    Use the YZ event for vertical areas.

Capture or paint depth

1. Choose the depth channels

For a standalone field, set the row to Heightfield Only and enable the channels you need. For a texture or render target, keep that source and route its color channels to the depth channel you will paint.
Heightfield Only with Red enabled
  1. Enable the channels you need
    Enabled channels return 1 inside and 0 outside their painted interval.

2. Capture the scene

Select the Play Area. Under Scene Capture, choose Target Row and Write Channel. Hide unwanted meshes in the World Outliner. Click Capture Scene, wait for processing, then Save Field. No special mesh materials are needed.
Play Area capture destination and Capture Scene button
  1. Choose the destination
    Target Row is zero-based. Write Channel selects R, G, B or A.
  2. Capture, then save
    Hide unwanted geometry in the Outliner first.

3. Paint or adjust it

Click Open Painter. Select the row and channel. Choose Set, Raise, Lower, Erase, or Smooth. Adjust Radius and Falloff, then drag over the plane. Save when finished.
Heightfield Painter with channel, boundary and brush controls
  1. Channel and brush
    Choose R/G/B/A, then Set, Raise, Lower, Erase or Smooth.
  2. Brush size and falloff
    Adjust these before dragging across the plane.

4. Choose height storage

Select Height Storage in the asset: 8-, 16-, or 32-bit. Return Color Format separately selects RGBA8 or RGBA16F.
Height Storage set to 16-bit / Scaled
  1. Stored depth precision

5. Set runtime resolution

Choose Runtime Resolution and save. Your original capture stays editable at its authoring resolution.
Authoring resolution and independently selected runtime resolution
  1. Runtime size
    Lower this without losing the original authoring data.

Add overlap events

1. Name the source

Create a Pixel Era Overlap Emulator asset. Add Fire and note its Source Index. Choose a preview mesh and material.
Fire source card in the Overlap Emulator
  1. Name the effect
    This is the name received by Blueprint events.
  2. Remember the source index
    Use the same index in its material instance.

2. Prepare the material

Add Pixel Era: Overlap Source. Connect its WPO output to World Position Offset, even without animation.
Overlap Source WPO output connected to the material
  1. Connect WPO
    Keep this connection even for a static source.

3. Match the source

In the material instance, set PESourceIndex to Fire’s index. Set PixelEraCollisionEnabled to 1. Assign the material to your mesh.
Source index and participation settings in the material instance
  1. Match Source Index
    Use Fire’s source index, 0 in this example.
  2. Participation: 1
    Keep PixelEraCollisionEnabled at 1.

4. Prepare the mesh

Enable Allow CPU Access on the Static Mesh and disable Nanite. Use a closed mesh for inside-volume detection. Engine collision may be disabled.
Static Mesh Allow CPU Access setting
  1. Nanite: off
  2. Allow CPU Access: on

5. Place the manager

Add one Pixel Era Overlap Manager and assign your Overlap Emulator asset. Place your prepared source mesh.
Overlap Manager assigned DA_FireSource
  1. Assign your Overlap Emulator

6. Add the receiver

Add Pixel Era Overlapper to your actor. Adjust Radius, Height, and relative location.
Overlapper capsule size and sweep settings
  1. Capsule dimensions
    Height is the full height, including both caps.
  2. Sweep Movement
    Enabled by default. Disable before teleporting, then re-enable after the move.

7. React to Fire

Select Overlapper in the Blueprint. Under Events, click + for On Begin Overlap. Loop through Source Names, then use Switch on Name → Fire.
Begin Overlap source-name loop and Fire response
  1. Begin Overlap
    Loop through the names to trigger each effect.

End the response

Use On End Overlap the same way.
End Overlap source-name loop and Fire response
  1. End Overlap
    Use the matching source names to stop their response.

GPU-only reads: Materials

1. Create the shared key

Create a Pixel Era GPU Ledger data asset. Enter SharedColor in New Key and click AddKey. Leave Slots Per Key at 1 and save.
GPU ledger containing SharedColor with one slot
  1. Name the key
    Enter SharedColor.
  2. Click AddKey
    Keep Slots Per Key at 1, then save the asset.

2. Write the color

In Blueprint, call Pixel Era: Read Global with Source, UV, Ledger, and Request Key. Call again whenever it needs updating. This GPU-only path needs no Pixel Era Manager actor.
Blueprint Read Global writing SharedColor
  1. Shared key
    Use SharedColor in both the writer and receiver.

3. Select the shared value

Add Pixel Era: Receive in your material. In its Details, select the same Ledger and Request Key.
Receive node Details with ledger and SharedColor
  1. Choose the ledger
  2. Choose SharedColor
    Use the same key as Read Global.

4. Use the output

Leave Key Offset disconnected for this single value. Connect RGB, Alpha, or RGBA to the effect you want to control.
Material Receive configured for SharedColor
  1. Latest shared color
    RGB feeds Emissive Color in this example.

Only need a local read?

Use Pixel Era: Read Local with a Texture Object and UV. Its RGBA output needs no ledger or publishing step.
Read Local connected to a Texture Object and UV
  1. Source texture
    Select the Texture Object and assign your source in Details.

GPU-only reads: Niagara

1. Set up the parameter

Create a one-slot ledger key using Share a color on the GPU. Set your emitter to GPU Compute Sim and spawn one particle. Add a user parameter of type Pixel Era GPU Ledger. Assign its Ledger, Request Key, and Source Texture.
Niagara GPU emitter and its populated Pixel Era GPU Ledger user parameter
  1. Assign the ledger
    Use the asset containing SharedColor.
  2. Choose the source
    Required for Read Global; not required for Receive.

2. Read and use the color

Add Pixel Era: Read Global in Particle Update. Bind GPU Ledger to your user parameter, set UV, and keep Key Offset at 0. Add a later Set Particles.Color module and bind its color to Read Global’s Output Color.
Read Global module inputs bound to the user parameter
  1. Bind the user parameter
    ProbeLedger is this example’s user parameter.
  2. Use Output Color
    Bind it to Particles.Color or another compatible input.

Receive an existing key

Use Pixel Era: Receive instead, bound to the ledger parameter. Its Output Color works the same way.
Receive module and its Output Color binding
  1. Receive the shared value
    Bind Output Color in the same way.

Read colors in C++

1. Add and configure the example

Copy the complete header and source below into your game module, then build. Place Pixel Era Manager and the example actor. Assign its Manager and prepared Source. The actor keeps one sample handle.
C++ retained sample creation during BeginPlay
  1. Register once
    Retain the returned sample handle.
Copy the C++
// Actor header: retain one registration.
#include "PixelEraSample.h"
FPixelEraSample Sample;

// BeginPlay: Manager and Source are assigned actor properties.
if (Manager && Source)
{
    Sample = Manager->CreateTextureSample(
        GetFName(), Source, UV, EPixelEraSamplePrecision::RGBA8);
    Manager->AddTickPrerequisiteActor(this);
}

2. Update, receive, remove

Change the actor’s UV. Tick updates the retained handle, then stores the latest completed color in PixelColor. EndPlay removes the registration. Keep these calls on the game thread. Give every sample a key unique within its manager.
C++ UV update, latest-color read and EndPlay cleanup
  1. Update UV
    The handle keeps the existing registration.
  2. Remove on EndPlay
    If this read operation will not be used again, and it should not tick anymore – remove the sample from the manager’s cache.
Copy the C++
// Tick: update the retained sample.
Sample.SetUV(UV);
FLinearColor LatestColor;
int64 Sequence = 0;
if (Sample.GetPixelColorWithSequence(LatestColor, Sequence))
{
    PixelColor = LatestColor;
}

// EndPlay: remove the registration.
Sample.Remove();

Add "PixelEra" to PublicDependencyModuleNames in your module’s .Build.cs.

Complete header

PETextureReaderExample.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PixelEraSample.h"
#include "PETextureReaderExample.generated.h"

class APixelEraCachedReader;
class UTexture;

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

public:
    APETextureReaderExample();

    UPROPERTY(EditInstanceOnly, Category = "Pixel Era")
    TObjectPtr<APixelEraCachedReader> Manager;

    UPROPERTY(EditAnywhere, Category = "Pixel Era")
    TObjectPtr<UTexture> Source;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pixel Era")
    FVector2D UV = FVector2D(0.5, 0.5);

    UPROPERTY(BlueprintReadOnly, Category = "Pixel Era")
    FLinearColor PixelColor = FLinearColor::Black;

protected:
    void BeginPlay() override;
    void Tick(float DeltaSeconds) override;
    void EndPlay(const EEndPlayReason::Type Reason) override;

private:
    FPixelEraSample Sample;
};
Complete source

PETextureReaderExample.cpp

#include "PETextureReaderExample.h"
#include "PixelEraCachedReader.h"
#include "Engine/Texture.h"

APETextureReaderExample::APETextureReaderExample()
{
    PrimaryActorTick.bCanEverTick = true;
}

void APETextureReaderExample::BeginPlay()
{
    Super::BeginPlay();
    if (Manager && Source)
    {
        Sample = Manager->CreateTextureSample(
            GetFName(), Source, UV, EPixelEraSamplePrecision::RGBA8);
        Manager->AddTickPrerequisiteActor(this);
    }
}

void APETextureReaderExample::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);
    Sample.SetUV(UV);

    FLinearColor LatestColor;
    int64 Sequence = 0;
    if (Sample.GetPixelColorWithSequence(LatestColor, Sequence))
    {
        PixelColor = LatestColor;
    }
}

void APETextureReaderExample::EndPlay(const EEndPlayReason::Type Reason)
{
    Sample.Remove();
    Super::EndPlay(Reason);
}

Use Overlapper in C++

1. Prepare the level

Follow Add overlap events through source and manager setup, naming your source Poison. Copy the complete header and source below into your game module, then build. The actor creates its Pixel Era Overlapper component.
C++ Overlapper construction and BeginPlay event binding
  1. Create the component
    Overlapper performs the query.
  2. Bind the events
    Your actor supplies the response.
Copy the C++
#include "PE_Overlapper.h"

AOverlapReceiver::AOverlapReceiver()
{
    Overlapper = CreateDefaultSubobject<UPE_Overlapper>(TEXT("Overlapper"));
    SetRootComponent(Overlapper);
    Overlapper->Radius = 34.f;
    Overlapper->Height = 180.f;
}

void AOverlapReceiver::BeginPlay()
{
    Super::BeginPlay();
    Overlapper->OnBeginOverlap.AddDynamic(this, &AOverlapReceiver::BeginOverlap);
    Overlapper->OnEndOverlap.AddDynamic(this, &AOverlapReceiver::EndOverlap);
}

2. Handle Begin and End

Place an OverlapReceiver in the level and move it through the source mesh. bPoisoned becomes true on entry and false on exit. Both handlers receive source-name arrays and use UFUNCTION() for their dynamic bindings.
C++ source-name handlers for Poison entry and exit
  1. Begin response
    Poison enters the capsule.
  2. End response
    Poison leaves the capsule.
Copy the C++
// Both handlers are declared with UFUNCTION() in the header.
void AOverlapReceiver::BeginOverlap(const TArray<FName>& SourceNames)
{
    if (SourceNames.Contains(FName(TEXT("Poison"))))
        bPoisoned = true;
}

void AOverlapReceiver::EndOverlap(const TArray<FName>& SourceNames)
{
    if (SourceNames.Contains(FName(TEXT("Poison"))))
        bPoisoned = false;
}

Add "PixelEraOverlap" to PublicDependencyModuleNames in your module’s .Build.cs.

Complete header

OverlapReceiver.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "OverlapReceiver.generated.h"

class UPE_Overlapper;

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

public:
    AOverlapReceiver();

protected:
    virtual void BeginPlay() override;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pixel Era")
    TObjectPtr<UPE_Overlapper> Overlapper;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Gameplay")
    bool bPoisoned = false;

    UFUNCTION()
    void BeginOverlap(const TArray<FName>& SourceNames);

    UFUNCTION()
    void EndOverlap(const TArray<FName>& SourceNames);
};
Complete source

OverlapReceiver.cpp

#include "OverlapReceiver.h"
#include "PE_Overlapper.h"

AOverlapReceiver::AOverlapReceiver()
{
    Overlapper = CreateDefaultSubobject<UPE_Overlapper>(TEXT("Overlapper"));
    SetRootComponent(Overlapper);
    Overlapper->Radius = 34.f;
    Overlapper->Height = 180.f;
}

void AOverlapReceiver::BeginPlay()
{
    Super::BeginPlay();
    Overlapper->OnBeginOverlap.AddDynamic(this, &AOverlapReceiver::BeginOverlap);
    Overlapper->OnEndOverlap.AddDynamic(this, &AOverlapReceiver::EndOverlap);
}

void AOverlapReceiver::BeginOverlap(const TArray<FName>& SourceNames)
{
    if (SourceNames.Contains(FName(TEXT("Poison"))))
        bPoisoned = true;
}

void AOverlapReceiver::EndOverlap(const TArray<FName>& SourceNames)
{
    if (SourceNames.Contains(FName(TEXT("Poison"))))
        bPoisoned = false;
}

Search Pixel Era

Type at least two characters to search.