quarta-feira, 21 de outubro de 2020

A macro UCLASS( )

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.

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.


 

Sumário C++