TArray é um tipo de container que armazena um ou mais elementos de um mesmo tipo. Container é um tipo de classe cujas instâncias são coleções de outros objetos. Outros exemplos de container em Unreal C++ são TSet e TMap, que serão vistos nos próximos artigos.
Uma forma simples de entender o conceito de Array é visualizar no editor da Unreal. Este código cria um Array com o nome TownNames para armazenar elementos do tipo FString.
UPROPERTY(EditAnywhere, Category=ArrayTown)
TArray<FString> TownNames;
A imagem abaixo mostra o Array no editor. Você pode adicionar elementos clicando no ícone +. Os números do lado esquerdo são os índices dos elementos do Array. O primeiro elemento de um Array possui o índice zero.
Duas função podem ser usadas para adicionar elementos em um Array usando C++. A função Add() adiciona elementos no final do Array e a função Insert() adiciona um elemento no índice passado como parâmetro.
TownNames.Add(TEXT("Tarrin"));
TownNames.Insert(TEXT("Pitmerden"), 2);
Você pode ler e modificar elementos de um Array usando o operador [] e o índice do elemento.
FString FirstTown = TownNames[0];
TownNames[3] = TEXT("Penkurth");
Cuidado, se você usar um índice menor que 0 ou igual ou maior que o número de elementos de um Array, irá gerar um erro em tempo de execução.
Para saber o número de elementos de um Array, use a função Num():
int32 NumberOfElements = TownNames.Num();
Exemplo de uso:
Vamos criar um Array para guardar referências de instâncias de Actor e depois escrever na tela os nomes das instâncias que foram adicionadas ao Array.
Crie uma classe C++ com o nome TestTArray usando como classe pai a classe Actor. No arquivo TestTArray.h, adicione a declaração dos componentes e do TArray como mostra este código:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TestTArray.generated.h"
UCLASS()
class TUTOPROJECT_API ATestTArray : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestTArray();
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=ArrayExample)
TArray<AActor*> SelectedActors;
};
Este é o conteúdo do arquivo TestTArray.cpp:
#include "TestTArray.h"
ATestTArray::ATestTArray()
{
// 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 ATestTArray::BeginPlay()
{
Super::BeginPlay();
FString Message;
if(SelectedActors.Num() > 0)
{
Message = FString::Printf(TEXT("Number of elements in the array: %d"),
SelectedActors.Num());
if(GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
Message = FString::Printf(TEXT("--- Selected Actors ---"));
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
for (AActor* ActorInstance : SelectedActors)
{
Message = FString::Printf(TEXT("Instance Name: %s"),
*(ActorInstance->GetName()));
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, Message);
}
}
}
}
// Called every frame
void ATestTArray::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Na função BeginPlay() usamos um ranged-based for loop para iterar nos elementos do Array e escrever na tela o nome de cada instância.
Compile o código C++ e adicione uma instância de TestTArray no nível. Você pode adicionar elementos no Array usando a aba Details da instância.
Inicie o jogo e veja na tela os nomes das instâncias de Actor: