TMap é outro tipo de container muito usado na Unreal Engine. Os elementos de um Map são pares de chave-valor. O tipo da chave pode ser diferente do tipo do valor. Não é permitido ter chaves duplicadas. A busca por elementos é feita usando o valor da chave.
Este código cria um TMap que pode ser modificado no editor. O tipo da chave é FString e o tipo do valor é float.
UPROPERTY(EditAnywhere, Category=MapExample)
TMap<FString, float> PriceTable;
Para adicionar elementos em um TMap, use a função Add() passando como parâmetros a chave e o valor.
PriceTable.Add( TEXT("Axe"), 37.5f );
PriceTable.Add( TEXT("Hammer"), 25.0f );
PriceTable.Add( TEXT("Spear"), 18.0f );
Use a função Remove() passando a chave como parâmetro para remover um elemento de um TMap.
PriceTable.Remove( TEXT("Hammer") );
A função Empty() remove todos os elementos de um TMap.
PriceTable.Empty();
A quantidade de elementos de um TMap é obtido usando a função Num().
int32 NumberOfElements = PriceTable.Num();
A função Find() recebe como parâmetro a chave e retorna um ponteiro para o valor associado à chave. Se a chave não for encontrada será retornado um ponteiro nulo (nullptr).
float* PtrPrice = PriceTable.Find( TEXT("Spear") );
A iteração em um TMap pode ser feita usando um ranged-based for loop. Um elemento de um TMap é do tipo TPair que possui as variáveis Key e Value. Para simplificar, você pode usar a palavra chave C++ auto junto com o operador & para definir a referência para um elemento do TMap como mostra o código abaixo.
for (auto& ItemPrice : PriceTable)
{
UE_LOG(LogTemp, Warning, TEXT("%s - %.2f"), *(ItemPrice.Key), ItemPrice.Value);
}
O caractere especial %s será substituído pelo conteúdo da variável ItemPrice.Key. É necessário colocar o operador * antes de variáveis do tipo FString. O valor de ItemPrice.Value substituirá os caracteres %.2f e será exibido com duas casas decimais.
Exemplo de uso:
Crie uma classe C++ com o nome TestTMap usando como classe pai a classe Actor. No arquivo TestTMap.h, adicione a declaração dos componentes e do TMap:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TestTMap.generated.h"
UCLASS()
class TUTOPROJECT_API ATestTMap : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestTMap();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(VisibleAnywhere)
USceneComponent* RootScene;
UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* StaticMesh;
UPROPERTY(EditAnywhere, Category=MapExample)
TMap<FString, float> PriceTable;
};
Será usado um ranged-based for loop na função BeginPlay() para escrever na tela o nome e preço dos elementos do TMap. O conteúdo do arquivo TestTMap.cpp fica assim:
#include "TestTMap.h"
ATestTMap::ATestTMap()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
RootScene = CreateDefaultSubobject<USceneComponent>("RootScene");
RootComponent = RootScene;
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");
StaticMesh->SetupAttachment(RootScene);
}
// Called when the game starts or when spawned
void ATestTMap::BeginPlay()
{
Super::BeginPlay();
FString Message;
if(PriceTable.Num() > 0)
{
Message = FString::Printf(TEXT("Number of elements in the Map: %d"),
PriceTable.Num());
if(GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
for(auto& ItemPrice : PriceTable)
{
Message = FString::Printf(TEXT("%s - %.2f"), *(ItemPrice.Key), ItemPrice.Value);
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
}
}
}
}
// Called every frame
void ATestTMap::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Compile o código C++ e adicione uma instância de TestTMap no nível. Adicione elementos no TMap usando a aba Details da instância. Você não conseguirá adicionar uma chave duplicada.
Inicie o jogo e veja na tela os nomes e preços dos elementos adicionados ao TMap: