Runtime Mask Access
Errant Biomes mask data can be accessed in runtime allowing you to drive your game logic by your world metadata.
Our subsystem will handle optimal streaming and caching of the data, leaving you with a simple performant interface for access.
Examples of use cases include:
- Playing audio based on player location in a biome.
- Limiting player allow behaviour based on nearby enviroment type.
- Controlling player hazards like area temperature with same data that is then used to generate enviroment.
Mask Setup
For mask to be available in runtime the Is Editor Only
property needs to be set to false(unchecked).
Custom Material Mask
This feature composes well with Custom Material Masks.
Custom material mask can be used for offline calculation/preperation of runtime accesed data for improved performance.
For example: Take a mask used to indicate water, calculate expanded, blurred area of that mask for better transitions and elimination of the need for sampling over a larger area in runtime.
Runtime Access
Access to the data is done through the UBiomesMaskWorldSubsystem
, mostly through the SampleMask
method.
The subsystem will manage streaming and caching data from masks.
Code Example
Provided here is an example implementation of a simple actor that samples mask under its location in runtime.
// BiomesSamplerTest.h
#pragma once
#include "CoreMinimal.h"
#include "BiomesMaskAsset.h"
#include "BiomesMaskWorldSubsystem.h"
#include "Components/StaticMeshComponent.h"
#include "Engine/World.h"
#include "GameFramework/Actor.h"
#include "BiomesSamplerTest.generated.h"
UCLASS()
class CURRENT_API ABiomesSamplerTest : public AActor
{
GENERATED_BODY()
public:
ABiomesSamplerTest()
{
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
auto* MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
MeshComponent->SetStaticMesh(LoadObject<UStaticMesh>(nullptr, TEXT("StaticMesh'/Engine/BasicShapes/Cube.Cube'")));
MeshComponent->SetupAttachment(RootComponent);
}
virtual void Tick(float DeltaTime) override
{
if (!GetWorld() || !MaskAsset)
{
return;
}
UBiomesMaskWorldSubsystem* Subsystem = GetWorld()->GetSubsystem<UBiomesMaskWorldSubsystem>();
const float Value = Subsystem->SampleMask(*MaskAsset, FVector2D(GetActorLocation())).Get(FFloat16::MaxF16Float);
UE_LOG(LogTemp, Warning, TEXT("Sampled value: %f"), Value);
}
UPROPERTY(EditAnywhere, Category = "Test")
TObjectPtr<UBiomesMaskAsset> MaskAsset;
};