sexta-feira, 23 de outubro de 2020

The UPROPERTY() macro

The UPROPERTY() macro is used to expose variables to the Unreal Engine editor and to include the property in the Unreal Engine memory management system.

The UPROPERTY() macro is placed on the line above the definition of the C++ variable as shown in the example below:

UPROPERTY(EditAnywhere, Category = Tutorial)
int32 SpecialId;

The parameters of UPROPERTY() are called property specifiers. In the example above were used EditAnywhere and Category that is used to group variables in the properties window. The use of quotation marks is optional in the Category name, but necessary if the Category name has a blank space.

Let's look at a group of six property specifiers. A property can only use one specifier from that group of six that is listed below. These six specifiers are a combination of two pieces of information. The first information is whether the property is read-only (Visible) or editable (Edit). The second information is related to where the property appears, which can be only in instances (InstanceOnly), only in the Blueprints editor (DefaultsOnly), or both (Anywhere).

The six specifiers are these:

  • VisibleInstanceOnly: Read-only, appears in the instance properties window.
  • VisibleDefaultsOnlyRead-only, appears in the Blueprints editor properties window. 
  • VisibleAnywhere: Read-only, appears in the properties window of the instances and of the Blueprints editor. 
  • EditInstanceOnlyEditable, appears in the instance properties window. 
  • EditDefaultsOnlyEditable, appears in the Blueprints editor properties window. 
  • EditAnywhereEditable, appears in the properties window of the instances and of the Blueprints editor.


Component pointers usually have the VisibleAnywhere specifier. This prevents the pointer from being changed, but the component properties can be modified.
 
The two specifiers below indicate how the property will be used in a Blueprint Event Graph. If neither specifier is present, the property is not listed for use in the Event Graph.
  • BlueprintReadOnly: It can be read but cannot be modified in the Event Graph.
  • BlueprintReadWriteIt can be read and modified in the Event Graph.

There is another type of specifier known as Metadata. These are some examples:
  • DisplayName="Property Name"Name that will be displayed in the properties window.
  • ClampMin="N": Minimum value that can be entered for a property. It can be used in properties of type integer and float.
  • ClampMax="N": Maximum value that can be entered for a property. It can be used in properties of type integer and float. 

To use a Metadata specifier use the word meta, and put the specifiers within the parentheses as shown below: 
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Tutorial, 
          meta=(DisplayName="Special Identification", ClampMin="0", ClampMax="999") )
int32 SpecialId;


Example usage: 

Create a C++ class with the name TestUProperty using the Actor class as the parent class. In the TestUProperty.h file, add the definition of three variables as shown in the code below:

#pragma once

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

UCLASS()
class TUTOPROJECT_API ATestUProperty : public AActor
{
  GENERATED_BODY()
	
public:	
  // Sets default values for this actor's properties
  ATestUProperty();
	
  UPROPERTY(EditInstanceOnly, Category = Tutorial)
  FString NPCName;
	
  UPROPERTY(VisibleDefaultsOnly, Category = Tutorial)
  float BaseClassVersion;
	
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Tutorial,
            meta=(DisplayName="Special Identification", ClampMin="0", ClampMax="999") )
  int32 SpecialId;

...


In the TestUProperty.cpp file, assign an initial value to the BaseClassVersion variable within the constructor:
#include "TestUProperty.h"

ATestUProperty::ATestUProperty()
{
  // Set this actor to call Tick() every frame.
  PrimaryActorTick.bCanEverTick = true;

  BaseClassVersion = 0.3f;
}

...


Compile the code and add an instance of TestUProperty at the level. You will not be able to move the instance on the level because we have not defined a RootComponent for it. But you can select the instance using the World Outliner.

See in the Details tab that the NPCName and Special Id properties appear and are editable, but the BaseClassVersion variable does not appear because the VisibleDefaultsOnly specifier indicates that it should only appear in the Blueprints editor.


Special Identification is the name that was assigned to the SpecialId variable using the DisplayName specifier. The specifiers ClampMin and ClampMax define the range of possible values for SpecialId. If you enter a value greater than 999 the editor automatically changes to 999.

Agora vamos criar um Blueprint baseado na classe C++ TestUProperty para vermos a variável BaseClassVersionNavegue até a pasta das classes C++ usando o Content Browser do editor e clique com o botão direito na classe TestUProperty. Escolha a opção Create Blueprint class based on TestUProperty.

Now we are going to create a Blueprint based on the C++ TestUProperty class to see the BaseClassVersion variable. Navigate to the C++ class folder using the editor's Content Browser and right-click on the TestUProperty class. Choose the option Create Blueprint class based on TestUProperty.


Open the new Blueprint and click the Class Defaults button. Note that the BaseClassVersion variable appears but is not editable and the NPCName variable does not appear, because it should only appear in instances.


Right-click on the Blueprint EventGraph and search using the word "special". Note that the Get and Set functions for the SpecialId variable appear. This is due to the BlueprintReadWrite specifier. The other two variables do not appear in the Actions list.


The Blueprint Actions list used the name that was in the DisplayName specifier of the SpecialId variable, but the Blueprint nodes used the variable name as it is in the code. 


Table of Contents C++