quarta-feira, 4 de novembro de 2020

The UObject class

The UObject class is the base class for all Unreal Engine objects. It provides a set of important services such as reflection, serialization, networking, and memory management.

UObject instances cannot be added to the level. They must be part of an Actor. If you want to create a class that can be instantiated at the level, it has to inherit from AActor.

Classes that inherit from UObject but do not inherit from AActor have the prefix U. As an example we have the UActorComponent class that represents the components that are added in an Actor.

To create an instance of a UObject subclass, use the NewObject() function. The line below shows an example, assuming that the UObjectChild class is a subclass of UObject:

UObjectChild* ObjectChild = NewObject<UObjectChild>(this,UObjectChild::StaticClass());

The Unreal Engine will manage the memory of this object and destroy it when it is no longer needed. But if you want to destroy an instance of UObject, you can use the ConditionalBeginDestroy() function and assign nullptr to the pointer:

ObjectChild->ConditionalBeginDestroy();
ObjectChild = nullptr;


Example usage:

Create a C++ class with the name RpgDiceSet using the Object class as the parent class. It is necessary to check the Show All Classes option so that the Object class is listed as shown in the image.



The RpgDiceSet class will represent a set of five dice. It has the RollDice() function to roll the dice and the ResultString() function that returns the result of the dice.

In the RpgDiceSet.h file, add the following code:

...

UCLASS()
class TUTOPROJECT_API URpgDiceSet : public UObject
{
  GENERATED_BODY()

//For simplicity, the variables are public.	
public: 
	
// Note for non-native English readers:
// Die is the singular of Dice.
  
  int32 Die1;
  int32 Die2;
  int32 Die3;
  int32 Die4;
  int32 Die5;
  
  void RollDice(int32 NumFaces);

  FString ResultString();
	
}; 

In the RpgDiceSet.cpp file, add the implementation of the two functions shown below:

#include "RpgDiceSet.h"

void URpgDiceSet::RollDice(int32 NumFaces)
{  
  if(NumFaces >= 2 && NumFaces <= 20)
  {
    Die1 = FMath::RandRange(1, NumFaces);
    Die2 = FMath::RandRange(1, NumFaces);
    Die3 = FMath::RandRange(1, NumFaces);
    Die4 = FMath::RandRange(1, NumFaces);
    Die5 = FMath::RandRange(1, NumFaces);
  }
  else
  {
    Die1 = 0;
    Die2 = 0;
    Die3 = 0;
    Die4 = 0;
    Die5 = 0;	
  }
}
  
FString URpgDiceSet::ResultString()
{
	  
  FString Result = FString::Printf(
                      TEXT("Die 1: %d; Die 2: %d; Die 3: %d; Die 4: %d; Die 5: %d;"), 
                      Die1, Die2, Die3, Die4, Die5);
									 
  return Result;
									 
}

The RollDice() function has the NumFaces parameter that indicates the number of faces of the dice. An integer value between 2 and 20 must be passed. The function FMath::RandRange(int32 Min, int32 Max) returns a random integer value >= Min and <= Max.

The ResultString() function returns an FString containing the results of all dice.

Now create a C++ class with the name TestUObject using the Actor class as the parent class. In the TestUObject.cpp file, add the #include "RpgDiceSet.h" and implement the BeginPlay() function like this:

#include "TestUObject.h"
#include "RpgDiceSet.h"

void ATestUObject::BeginPlay()
{
  Super::BeginPlay();
	
  URpgDiceSet* RpgDiceSet = NewObject<URpgDiceSet>(this, URpgDiceSet::StaticClass());

  RpgDiceSet->RollDice(20);
	
  if(GEngine)
  {
    GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, 
                                     RpgDiceSet->ResultString() );
  }

  RpgDiceSet->ConditionalBeginDestroy();
  RpgDiceSet = nullptr;	
}

...

The BeginPlay() function creates an instance of the URpgDiceSet class, calls its functions, shows the result on the screen, and then starts destroying the instance that was created.

Compile the C++ code and add an instance of TestUObject at the level. Start the game and see the results of the dice being displayed on the screen. The image below shows one of the executions:



Table of Contents C++