A macro UCLASS() é usada para indicar que uma classe C++ fará parte do sistema de Reflexão da Unreal. Isto é necessário para que a classe C++ seja reconhecida pelo editor da Unreal Engine. Outra vantagem do uso da UCLASS() é o de poder utilizar o sistema de gerenciamento de memória da Unreal Engine na classe C++.
A compilação de um projeto C++ da Unreal ocorre em duas fases. Na primeira fase a UnrealHeaderTool (UHT) lê os arquivos C++ headers buscando pelas macros da Unreal e gera o código necessário que substituirá as macros. Na segunda fase o compilador C++ compila o código resultante.
A macro UCLASS() é colocada na linha acima da definição da classe C++. O código abaixo é o início do arquivo TutoProjectCollectable.h que foi criado na Parte I.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TutoProjectCollectable.generated.h"
UCLASS()
class TUTOPROJECT_API ATutoProjectCollectable : public AActor
{
GENERATED_BODY()
...
Para esta classe, o UnrealHeaderTool irá gerar código que será colocado no arquivo TutoProjectCollectable.generated.h e código que substituirá a macro GENERATED_BODY().
Um exemplo de código gerado pela UnrealHeaderTool é a função StaticClass() que é usada para retornar um ponteiro para a UClass que representa a classe C++. Esta função é static, ou seja, você não precisa de uma instância para chamar a função, basta usar o nome da classe.
Nós usamos a função StaticClass() na classe ATutoProjectGameMode na Parte I para definir a classe HUD usada pelo jogo:
HUDClass = ATutoProjectHUD::StaticClass();
A macro UCLASS() possui parâmetros que são conhecidos como especificadores de classes que definem o comportamento da classe. Os dois mais comuns são:
- Blueprintable: Indica que podem ser criados Blueprints usando a classe C++ como classe pai.
- BlueprintType: Indica que a classe C++ pode ser usada como tipo de variável em Blueprints.
O especificador Blueprintable é herdado pelas classes filhas (subclasses). Por exemplo, a classe AActor possui este especificador, então se você criar uma classe C++ usando a classe AActor como classe pai, não precisa colocar Blueprintable na nova classe.
Tem também o especificador NotBlueprintable. Você pode usá-lo caso esteja criando uma subclasse de AActor mas não quer permitir a criação de Blueprints baseados na sua classe C++.
Exemplo de uso:
Crie uma classe C++ com o nome TestUClass usando como classe pai a classe Object que é a classe base para objetos da Unreal Engine. É preciso marcar a opção Show All Classes para que a class Object seja listada como mostra a imagem.
No arquivo TestUClass.h, adicione os especificadores Blueprintable e BlueprintType dentro dos parênteses de UCLASS() como mostra este código:
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "TestUClass.generated.h"
UCLASS(Blueprintable, BlueprintType)
class TUTOPROJECT_API UTestUClass : public UObject
{
GENERATED_BODY()
};
Compile o código. Navegue até a pasta da nova classe C++ usando o Content Browser do editor da Unreal e clique com o botão direito na classe. Verifique que a opção Create Blueprint class based on TestUClass está habilitada como mostra a imagem abaixo. Se em nosso exemplo não tivesse o Blueprintable, esta opção estaria desabilitada.
Crie uma nova variável em um Blueprint. Clique no campo Variable Type para selecionar o tipo. Use o campo de pesquisa para filtrar os tipos e veja que a classe TestUClass está disponível para ser usada como um tipo. Se não tivesse o BlueprintType nesta classe, ela não seria listada.