sábado, 28 de novembro de 2020

A macro UENUM()

Uma enumeração é um tipo de dado que contém um conjunto de constantes nomeadas. O valor de uma variável cujo tipo é uma enumeração está restrito ao conjunto de constantes definido na enumeração. A macro UENUM() permite a criação de enumerações que podem ser usadas no Editor da Unreal e em Blueprints.

Na Unreal Engine as enumerações possuem o prefixo E em C++. Para implementar uma enumeração em C++, crie um arquivo cabeçalho (.h) com o nome da enumeração, por exemplo, TeamColor.h. O código abaixo mostra um exemplo de UENUM() que pode ser usada em Blueprints.

#pragma once

#include "CoreMinimal.h"
#include "TeamColor.generated.h"

UENUM( BlueprintType )
enum ETeamColor
{
  Blue,
  Red,
  Green	 UMETA( DisplayName = "GREEN" ),
  Yellow
};

O especificador BlueprintType permite que a enumeração seja usada como tipo de uma variável em um Blueprint. A macro UMETA( DisplayName = " ") é usada para mudar o nome da constante que será exibido no Editor. 

Nesta imagem está sendo criada uma variável com o nome ItemTeamColor usando a enumeração ETeamColor como tipo:


Uma variável do tipo enumeração é exibida na aba de detalhes de uma instância como um menu drop-down para o usuário selecionar o valor. 


Para definir uma variável do tipo enumeração em C++, use este Template:

TEnumAsByte< ETeamColor > ItemTeamColor;

A linha abaixo mostra como atribuir um valor à uma variável do tipo enumeração:

ItemTeamColor = ETeamColor::Red;

Nota: Se o editor da Unreal não estiver exibindo o último item da sua enumeração, reinicie o editor da Unreal que isto será corrigido. 


Exemplo de uso:

Vamos criar a enumeração EItemSize que poderá ser usada em outras classes para especificar o tamanho da instância no jogo. Crie o arquivo cabeçalho ItemSize.h e adicione este código:

#pragma once

#include "CoreMinimal.h"
#include "ItemSize.generated.h"

UENUM( BlueprintType )
enum EItemSize
{
  Small,
  Medium,
  Large
};

Vamos usar a enumeração EItemSize em uma classe C++. No editor da Unreal, crie uma classe C++ com o nome HealthPack usando como classe pai a classe Actor. O arquivo HealthPack.h deve ter este conteúdo:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ItemSize.h"
#include "HealthPack.generated.h"

UCLASS()
class TUTOPROJECT_API AHealthPack : public AActor
{
  GENERATED_BODY()
	
public:	
  // Sets default values for this actor's properties
  AHealthPack();

protected:
  // Called when the game starts or when spawned
  virtual void BeginPlay() override;

public:	
  // Called every frame
  virtual void Tick(float DeltaTime) override;

  int32 HealthPoints;
	
  UPROPERTY(EditAnywhere, Category=HealthPack)
  TEnumAsByte< EItemSize > PackSize;
	
  UPROPERTY(VisibleAnywhere)
  USceneComponent* RootScene;

  UPROPERTY(VisibleAnywhere)
  UStaticMeshComponent* StaticMesh;

};

Nós criamos a variável PackSize que é uma enumeração do tipo EItemSize. Você pode selecionar o valor de PackSize no editor. 

No arquivo HealthPack.cpp temos a criação dos componentes no construtor. O StaticMesh será definido no editor da Unreal. Na função BeginPlay()é feita a atribuição do valor da variável HealthPoints baseado no valor de PackSize.

#include "HealthPack.h"

AHealthPack::AHealthPack()
{
  // 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 AHealthPack::BeginPlay()
{
  Super::BeginPlay();
	
  if(PackSize == EItemSize::Small)
  {
    HealthPoints = 25;
  } 
  else if(PackSize == EItemSize::Medium)
  {
    HealthPoints = 50;
  }
  else if(PackSize == EItemSize::Large)
  {
    HealthPoints = 100;
  }

  FString Message = FString::Printf(TEXT("HealthPoints: %d"), HealthPoints);
                                    
  if(GEngine)
  {
    GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Red, Message);
  }  
}

// Called every frame
void AHealthPack::Tick(float DeltaTime)
{
  Super::Tick(DeltaTime);
}

No próximo artigo, veremos como usar o comando switch para selecionar ações baseadas nos valores de uma enumeração.

Compile o código C++ e adicione uma instância de HealthPack no nível. Você pode selecionar o valor de PackSize na aba Details da instância.



Sumário C++