home

Tutorial index

Unreal Engine 4: Tutorial 1 - Creating a new class, code overview

To create a new class, go into the classes folder, right click in the view displaying the contents of the folder, and select New Class. You will be presented with a list of base classes, Character is for controllable things, Pawn is for AI controlled things, and Actor is for.. just things! Each one inherits the next one, which means that Pawn has everything Actor has, and builds upon it, and Character has everything Pawn has, and builds upon it. During the first part of the tutorials we will be exploring how to spawn static meshes and other assets, and manipulate them. By the end of the tutorial we will have a pickup object, an object that we can interract with to pick it up, but does not act of its own accord, thus it has no AI, so we select Actor as a base class. We will look into Character and Pawn in later parts of the UE4 tutorials. After you have selected Actor, give it a name, "Pickup" is a suitable one if you don't have something else in mind. Once you have done that, Unreal should open Visual Studio for you, and have the class header and code files already open. If not, double click them through the content browser and they should open. If they do not, Visual Studio has probably not been set up correctly. (Not that formatting looks alot better in Visual Studio so take a look at it there frist to get an overview of its form)

Pickup.h:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "Pickup.generated.h"

UCLASS()
class TUTORIALPROJECT_API APickup : public AActor
{
GENERATED_BODY()

public:
// Sets default values for this actor's properties
APickup();

// Called when the game starts or when spawned
virtual void BeginPlay() override;

// Called every frame
virtual void Tick( float DeltaSeconds ) override;



};

Let's see what this code does. First of all, you have the #pragma once directive. This ensures that any includes that are already included in another header are not re-included, causing either redundency.

#include "Components/ActorComponent.h". This includes the components the Actor class uses, so you have access to it's default functionality. Best leave it as it is at the end of the includes.

#include "Pickup.generated.h". The .generated headers are, as they imply, generated by Unreal, and take care of the background stuff needed for the class so you don't have to. Unreal requires that this is strictly the last #include in the list.

UCLASS( ). C++-wise this is a macro, it informs Unreal of the class and some of its properties.

class TUTORIALPROJECT_API APickup : public AActor. Class declaration. TUTORIALPROJECT_API is again a macro, most probably occult Unreal stuff, and I am about 99% sure thatn 99% of developers never even bother to look a layer or two beneath, to see what it is. Otherwise this is just our class that extends from (inherits) AActor.

GENERATED_BODY(). Again a macro, this is meant to remain at the top of the class definition, it takes care of some stuff for unreal, as usual no need to bother, after all it is possible that any change you make will be overwritten in the next compilation.

public: . I presume you are somewhat familiar with Object Oriented Programmin (henceforth refered to as OOP), but just in case, this declares that anything that follows is visible and accessible from all classes, even if unrelated to this one.

APickup();. This is the constructor, when the object is first created, this function is called and sets all variables needed to their right values, as well as carries out any other procedure necessary. Note that stuff don't need to be visible for them to exist in the memory.

virtual void BeginPlay() override;. This is what is called when the object actually starts functioning, in most cases for you this means, when it is spawned. It is different than the constructor. Why have a different one? Consider a factory that makes robots, it may have some in stock and yet not spawn them until later. They are in stock and thus were created with the constructor, which referred to the circumstances prevailling at their manufacturing time. However, when it spawns them the circumstances are different, so perhaps there's not enough power to power them on so they have to be spawned as sleeping, or perhaps they have to check their surroundings to set their AI accordingly. It is virtual so it can be overriden in children classes, and it ends in override so it overrides the parent class's homonymous function. Note that putting override in the end is not standard C++ syntax.

virtual void Tick( float DeltaSeconds ) override;. Tick is the function in which this item is updated, it moves, changes AI, performs any actions initiated of its own free will etc. Stationary items without inate behavior, such as props thrown around the scene which only respond to other stuff, do not need anything to be done in this function. Its parameter is a float called DeltaSeconds, and is the elapsed time since the last update. This is passed so any movement or actually any time dependent action can retain its linearity in time regardless of any framerate drops. This prevents jugged movement and lag-like appearance.

 

Now let's see what code we have in the .cpp file.

// Fill out your copyright notice in the Description page of Project Settings.

#include "TutorialProject.h"
#include "Pickup.h"

// Sets default values
APickup::APickup()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void APickup::BeginPlay()
{
Super::BeginPlay();

}

// Called every frame
void APickup::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );

}


First off, the two includes. The first one includes your projects header file, which is generated for you. This allows access to any project-dependent information, but it's unlikely we will need anything from there, it's mostly Unreal that may reference that. The second is the header we saw just before, containing the declarations of the functions we are about to define.

APickup::APickup(). The constructor, as previously seen.

PrimaryActorTick.bCanEverTick = true;. This, as said in the comment, enables the Tick() function to be called on every frame. As stated previously, some object do not require it, in which case it is set to false. We leave it as is for now.

Super::BeginPlay();. In our BeginPlay() function, we merely call the corresponding function of the superclass, AActor.

Super::Tick( DeltaTime );. Similarly, we call the corresponding superclass function, giving it the timestep (time between previous and current update).

 

This covers the generated code, quite simple I believe. In the next tutorial we will add a static mesh to the class, and since we will do it in code, we can later make instances of the class have a random mesh (according to the properties of the pickup). For that we will follow this tutorial from the documentation of Epic Games, but we'll only keep the mesh-related part and try to undestand it clearly.