sábado, 1 de agosto de 2020

First contact with an Unreal C++ class

Let's start our C++ study by analyzing the TutoProjectGameMode.h file created by Unreal Engine for our project. This file is the header of the TutoProjectGameMode class.

This is the file content:
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "TutoProjectGameMode.generated.h"

UCLASS(minimalapi)
class ATutoProjectGameMode : public AGameModeBase
{
	GENERATED_BODY()

public:
	ATutoProjectGameMode();

};
The first line is a comment. Anything after the // characters until the end of the line is a comment. The comment is ignored when compiling the program and is useful for making notes about the code.

You can define a comment block that spans multiple lines. To do this, use the characters /* to start the comment. All of the following text will be a comment until the */ characters are found. Below is an example of this type of comment.
/*
    C++ Game Programming in Unreal Engine
    Author: Marcos Romero
*/

Lines beginning with the # character are called compilation directives. They are instructions used by the compiler during the compilation process. The #pragma once directive is used so that the file is included only once during compilation.

The #include directive inserts the content of the specified file in the position where the directive is. In C++ it is usually used to include header files that contain the specifications needed for the current file.

When creating a C++ class in Unreal Engine, a header file with the extension .generated.h is created. This file must always be the last file to be included with the #include directive.

The UCLASS(minimalapi) instruction is a macro that indicates that this class will be managed by Unreal Engine. A macro is replaced with a code block at the time of compilation.

The line below UCLASS() is the declaration of the TutoProjectGameMode class. Note that the class name is prefixed with the letter A. This prefix is placed by Unreal Engine and means that this class is part of the class hierarchy of the AActor class. This name with prefix A is used only in C++ code. In the Unreal editor, the class name remains TutoProjectGameMode.
class ATutoProjectGameMode : public AGameModeBase
{
   //class code...  
};

The text : public AGameModeBase after the class name indicates that the AGameModeBase class is the parent class of the ATutoProjectGameMode class. This is a concept known as inheritance, and it means that the variables and functions of the AGameModeBase class are part of the ATutoProjectGameMode class. We can also say that the ATutoProjectGameMode class is of type AGameModeBase.

A very important detail, the C++ language is case sensitivity so it distinguishes between uppercase and lowercase letters. If you use the name Atutoprojectgamemode to reference the ATutoProjectGameMode class, the compiler will generate an error because they are different names.

The characters { and } define a code block, which in this case is being used to define the contents of the ATutoProjectGameMode class.

The first line after { contains the text GENERATED_BODY(). This is an Unreal Engine macro that will generate the code necessary for Unreal Engine to manage this C++ class.

The public label indicates that the variables and functions defined below will be public, that is, they can be accessed by other C++ classes. The other access options for variables and functions are protected, where they are not accessible by other C++ classes but are accessible by child classes; and private, which are not accessible even by child classes. These labels are known as Access Modifiers.

In the line below public: we have the text ATutoProjectGameMode(); which is the declaration of the class Constructor. A Constructor has a block of code that is executed when an element of the class is created. This code block is defined in the TutoProjectGameMode.cpp file.

The character ; is a statement terminator in C++. You will soon become familiar with the lines that must be terminated with ;.