Pages

sábado, 28 de novembro de 2020

The UENUM() macro

An enumeration is a data type that contains a set of named constants. The value of a variable whose type is an enumeration is restricted to the set of constants defined in the enumeration. The UENUM() macro allows the creation of enumerations that can be used in the Unreal Editor and in Blueprints.

In Unreal Engine, the enumerations have the prefix E in C++. To implement an enumeration in C++, create a header file (.h) with the name of the enumeration, for example, TeamColor.h. The code below shows an example of UENUM() that can be used in Blueprints.

#pragma once

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

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

The BlueprintType specifier allows the enumeration to be used as the type of a variable in a Blueprint. The macro UMETA(DisplayName = " ") is used to change the name of the constant that will be displayed in the Editor.

In this image, a variable with the name ItemTeamColor is being created using the ETeamColor enumeration as type:


An enumeration type variable is displayed in the Details tab of an instance as a drop-down menu for the user to select the value.


To define an enumeration type variable in C++, use this Template:

TEnumAsByte< ETeamColor > ItemTeamColor;

The line below shows how to assign a value to an enumeration type variable:

ItemTeamColor = ETeamColor::Red;

Note: If the Unreal editor is not displaying the last item of your enumeration, restart the Unreal editor that this will be corrected.


Example usage:

Let's create the EItemSize enumeration that can be used in other classes to specify the size of the instance in the game. Create the ItemSize.h header file and add this code:

#pragma once

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

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

We will use the EItemSize enumeration in a C++ class. In the Unreal editor, create a C++ class named HealthPack using the Actor class as the parent class. The HealthPack.h file should have this content:

#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;

};

We created the variable PackSize which is an enumeration of type EItemSize. You can select the value of PackSize in the editor. 

In the file HealthPack.cpp we have the creation of the components in the constructor. The StaticMesh will be selected in the Unreal editor. In the BeginPlay() function, the value of the HealthPoints variable is assigned based on the value of 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);
}

In the next article, we will see how to use the switch statement to select actions based on the values of an enumeration.

Compile the C++ code and add an instance of HealthPack at the level. You can select the value of PackSize in the Details tab of the instance.



Table of Contents C++