quarta-feira, 21 de outubro de 2020

The UCLASS() macro

The UCLASS() macro is used to indicate that a C++ class will be part of Unreal's Reflection system. This is necessary for the C++ class to be recognized by the Unreal Engine editor. Another advantage of using UCLASS() is that you can use Unreal Engine's memory management system in the C++ class.

The compilation of an Unreal C++ project happens in two phases. In the first phase, UnrealHeaderTool (UHT) reads the C++ headers files looking for Unreal macros and generates the necessary code that will replace the macros. In the second phase, the C++ compiler compiles the resulting code.

The UCLASS() macro is placed on the line above the definition of the C++ class. The code below is the beginning of the TutoProjectCollectable.h file that was created in Part I.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TutoProjectCollectable.generated.h"

UCLASS()
class TUTOPROJECT_API ATutoProjectCollectable : public AActor
{
	GENERATED_BODY()

... 

For this class, UnrealHeaderTool will generate code that will be placed in the TutoProjectCollectable.generated.h file and code that will replace the GENERATED_BODY() macro.

An example of code generated by UnrealHeaderTool is the StaticClass() function that is used to return a pointer to the UClass that represents the C++ class. This function is static, that is, you don't need an instance to call the function, just use the class name.

We use the StaticClass() function in the ATutoProjectGameMode class in Part I to define the HUD class used by the game:

HUDClass = ATutoProjectHUD::StaticClass();


The UCLASS() macro has parameters that are known as class specifiers that define the behavior of the class. The two most common are:

  • Blueprintable: Indicates that Blueprints can be created using the C++ class as the parent class.
  • BlueprintType: Indicates that the C++ class can be used as a type of variable in Blueprints.


The Blueprintable specifier is inherited by child classes (subclasses). For example, the AActor class has this specifier, so if you create a C++ class using the AActor class as the parent class, you don't need to put Blueprintable in the new class.

There is also the NotBlueprintable specifier. You can use it if you are creating a subclass of AActor but do not want to allow the creation of Blueprints based on your C++ class.

 

Example usage:

Create a C++ class with the name TestUClass using the Object class as the parent class. The Object class is the base class for Unreal Engine objects. It is necessary to check the Show All Classes option so that the Object class is listed as shown in the image.


In the TestUClass.h file, add the Blueprintable and BlueprintType specifiers inside the parentheses of UCLASS() as shown in this code:

#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 the code. Navigate to the new C++ class folder using Unreal editor Content Browser and right-click on the class. Check that the Create Blueprint class based on TestUClass option is enabled as shown in the image below. If in our example there was no Blueprintable, this option would be disabled.


Create a new variable in a Blueprint. Click in the Variable Type field to select the type. Use the search field to filter the types and see that the TestUClass class is available to be used as a type. If it did not have BlueprintType in this class, it would not be listed.


 

Table of Contents C++