[UE5] First Steps from Blueprint into C++: Learning Three Macros with a Spinning Prop

Created: 2025-12-12Last updated: 2026-09-07

A diagrammed walkthrough of creating your first C++ class, for people who know Blueprint. Spin a prop, tune the speed in a child Blueprint, and call your own function from a node. Ties .h and .cpp, UCLASS/UPROPERTY/UFUNCTION, and builds and Live Coding into one exercise.

Can a variable written in C++ appear in the usual details panel? Does a function you wrote become a Blueprint node?

Start by trying those two on a small scale. In this article we build spinning logic for a prop in C++ and decide the rotation speed and stop timing in Blueprint. We work through one subject until code and nodes drive the same Actor.

Assembling Blueprint nodes on top of a C++ foundation

What You'll Learn

  • Creating your first C++ class and building it into a form UE can use
  • Reading the roles of .h, .cpp, and the three macros
  • Changing the C++ rotation speed in a child Blueprint's details panel
  • Calling your own function from a node to stop after 2 seconds and resume after 1

It assumes you have placed Actors in Blueprint and used variables and events. Even if C++ is new, the structure lets you prepare the two files shown and read them while watching what happens. The environment is Windows with Visual Studio.

Sponsored

What we split between C++ and Blueprint here

When finished, three identically shaped props stand in a row. One spins slowly, one spins fast, and one stays still. The math that spins them is the same; only the configured speed differs.

The finished image with the same prop moving at three speeds: 90, 360, and 0 degrees per second

A parent class is a plan holding shared construction; a child class inherits and tunes it. Here we make the C++ RotatingItem the parent and create three child Blueprints.

ResponsibilityWhat we write here
The C++ parentRotate a little each frame. Provide a switch for spinning and stopping
The child BlueprintChoose the look and speed. Build the "stop after N seconds" with nodes
C++ holds the rotation logic while the child Blueprint decides speed and stop timing

This structure could be built in Blueprint alone. Blueprint also has inheritance, project-wide search, and diffs, so it is not "always C++ because I want to reuse it."

C++ helps when, for example, you need an API not exposed to Blueprint, or you want to organize computation as text code. If speed is the goal, measuring the time first is what matters. Here the goal is not a speed comparison but making logic written in C++ usable from your everyday Blueprint.

Preparation: creating your first C++ class

1. Prepare an environment that can build C++

In the Visual Studio Installer, install the workloads your UE version needs, such as "Game development with C++." Visual Studio, MSVC, and the Windows SDK have compatible combinations, so check against your UE version in Epic's environment setup guide.

MSVC is the tool that converts C++ code into a runnable form, and the Windows SDK is the development components for building for Windows. Downloading and installing happens the first time, so finish it before adding a class.

2. Add a class with Actor as parent

Create a Third Person Blueprint project named CppFirstStep. Inside it, open "Tools → New C++ Class..."

  1. Choose "Actor" as the parent class and press "Next."
  2. Name it RotatingItem. Do not add a leading A.
  3. Use the CppFirstStep module as the destination. A module is a unit of code built together. If you choose Public, use the location generated as is.
  4. Press "Create Class" and wait for the automatic build to finish.

We choose Actor because we want to place it in the level and spin it. The wizard offers other parents, but we do not change it in this exercise. A Blueprint-only project becomes a project requiring builds once you add a C++ class.

3. Find the two files

Open RotatingItem.h and RotatingItem.cpp in Visual Studio. Both are under the project's Source folder.

FileRole
.h: the headerDeclares the variables this class holds and the functions callable
.cpp: the sourceWrites what actually happens when a function is called
Building the header's declarations and the source's logic produces a class UE can use

For example, "there is a function that changes whether it spins" is written in the .h, and "inside that function, rewrite the spinning flag" is written in the .cpp. The two together make one class.

The generated code's class name is ARotatingItem. The leading A marks a type derived from Actor. The file name and the RotatingItem you see in the editor carry no A.

Writing the code: a rotating Actor foundation

Once the automatic build finishes, save and close UE and leave Visual Studio open. Replace the two generated files with the following. If trying in a different project, keep only the CPPFIRSTSTEP_API in the class declaration as the name generated for that project.

MeshComponent points at the part that displays it, RotationSpeed is the rotation angle per second, and bSpinning is whether it is spinning. The header prepares these three plus the function we call.

RotatingItem.h

#pragma once

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

class UStaticMeshComponent;

UCLASS(Blueprintable)
class CPPFIRSTSTEP_API ARotatingItem : public AActor
{
    GENERATED_BODY()

public:
    ARotatingItem();
    virtual void Tick(float DeltaTime) override;

    UFUNCTION(BlueprintCallable, Category = "Rotation")
    void SetItemSpinning(bool bEnabled);

protected:
    // The part that displays the prop's appearance
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
    TObjectPtr<UStaticMeshComponent> MeshComponent;

    // Degrees rotated per second
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Rotation")
    float RotationSpeed = 90.0f;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Rotation")
    bool bSpinning = true;
};

RotatingItem.cpp

#include "RotatingItem.h"
#include "Components/StaticMeshComponent.h"

ARotatingItem::ARotatingItem()
{
    PrimaryActorTick.bCanEverTick = true;

    MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    SetRootComponent(MeshComponent);
    MeshComponent->SetMobility(EComponentMobility::Movable);
    MeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}

void ARotatingItem::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    if (bSpinning)
    {
        const float Angle = RotationSpeed * DeltaTime;
        AddActorLocalRotation(FRotator(0.0f, Angle, 0.0f));
    }
}

void ARotatingItem::SetItemSpinning(bool bEnabled)
{
    bSpinning = bEnabled;
}

Reading the logic in three parts

The first ARotatingItem::ARotatingItem() is the constructor. It prepares the parts and initial settings for when the object is created. Here it creates the display MeshComponent, makes it the root part, and sets it movable. Since this prop is for watching rotation, collision is disabled.

Tick is logic called every frame at runtime. bCanEverTick=true enables it and Super::Tick also calls the parent Actor's logic. The following if (bSpinning) is the condition "proceed inside if spinning."

Multiplying rotation speed by the seconds elapsed since the last frame to decide this frame's angle

DeltaTime is the seconds elapsed since the previous frame. Multiply 90 degrees/second by that and you get this frame's angle. Near 60 fps that is about 1.5 degrees per call. Even when frame count changes, you rotate an amount matching elapsed time.

FRotator is a type holding angles, and in C++ the arguments are Pitch, Yaw, Roll in that order. Here we put Angle into the middle Yaw and rotate around the Actor's own up axis. Place the props unrotated when testing.

The final SetItemSpinning simply puts the passed true or false into bSpinning. The time to stop can be decided from outside this function. We pass false from Blueprint later to stop the rotation.

Sponsored

The three macros: what they tell UE

The UCLASS, UPROPERTY, and UFUNCTION in the code are markers that make UE recognize C++ classes, variables, and functions. Notation that expands into fixed logic like this is called a macro.

The mechanism where UE inspects a class's structure and makes it usable from the details panel and Blueprint is called reflection. Thinking of it as "the entry point that tells the editor what you prepared in C++" makes it easier to read.

Attaching the respective macro to a class, variable, and function, specifying usage and telling UE
The notation hereWhat it enables in this example
UCLASS(Blueprintable)Create child Blueprints based on this class
UPROPERTY(EditAnywhere, BlueprintReadOnly)Tune the speed in the details panel and read it in the graph
UFUNCTION(BlueprintCallable)Call SetItemSpinning from a Blueprint node

Things inside the parentheses such as Blueprintable are called specifiers. The macro says "what to recognize" and the specifier says "how it may be used." UPROPERTY alone does not enable details editing and Get/Set; you combine the specifiers you need.

Note only the reading of the other symbols for now.

NotationWhat it means here
: public AActorInherits Actor's capabilities
public: / protected:C++ access scope. Separates functions used from outside from members used by this class and children
float / boolA type holding decimals / a type holding true and false
90.0f90 as a float. The trailing f marks the type
voidThe function returns no value
ARotatingItem::Specifies that this is the body of a RotatingItem function

GENERATED_BODY() and .generated.h are needed to connect to code UE generates. Leave them in place and make .generated.h the last include in the header. CPPFIRSTSTEP_API marks the class as usable from another module; use the generated one as is at first.

Build it and spin it in a child Blueprint

1. Build the C++

Building turns the code you wrote into a form UE can load and run. It is separate from Blueprint's "Compile" button.

  1. Save both files in Visual Studio. Confirm UE is closed.
  2. Set the configuration to "Development Editor" and the platform to "Win64."
  3. Right-click the game project CppFirstStep in Solution Explorer and run "Build."
  4. When the Output shows a successful build, open CppFirstStep.uproject.
Save and close UE, build with Development Editor and Win64, and reopen on success

Editor means "a build for use from the editor." If it fails, check the first error in the Output before reopening UE. Do not judge by red squiggles in the code alone; look at the build result.

2. Create a C++ child in Blueprint

Find RotatingItem under "C++ Classes → CppFirstStep" in the content browser. If it is not visible, enable "Show C++ Classes" in the settings.

Right-click RotatingItem and choose "Create Blueprint class based on RotatingItem." Save it under Content and name it BP_ItemSlow.

Where you workSetting
Components' MeshComponent → Static MeshCube from Engine's BasicShapes
MeshComponent → Transform ScaleAround X=0.35, Y=0.6, Z=0.2
MeshComponent → MobilityConfirm it is Movable
Class Defaults → RotationRotation Speed = 90

If you cannot find Cube, enable "Show Engine Content" in the asset picker. Making the shape oblong makes the change in facing during rotation easier to see.

Class Defaults are the initial settings for props made from this child Blueprint. The RotationSpeed written in C++ appears here as "Rotation Speed." Compile, save, and place it slightly above the floor in front of the Player Start, then Play.

If the prop spins, the C++ logic works in the child Blueprint too. We have not added the stop experiment yet, so at 90 degrees/second it takes 360 ÷ 90 = 4 seconds per revolution.

3. Make children with different speeds from the same parent

Duplicate BP_ItemSlow to create BP_ItemFast and BP_ItemStill. Both keep the C++ RotatingItem as parent. Change the speed in each one's Class Defaults and place the three apart.

Child BlueprintRotation SpeedExpected motion
BP_ItemSlow90One turn in 4 seconds
BP_ItemFast360One turn in 1 second
BP_ItemStill0Stays still

All three use the same rotation logic. You do not have to build C++ each time you change the speed — you can try it by changing the child Blueprint's value. If you have other visual assets, swapping only the Static Mesh is fine too.

Edit and Read: separating where you edit

We put two specifiers on RotationSpeed.

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Rotation")
float RotationSpeed = 90.0f;

EditAnywhere is for the details panel and BlueprintReadOnly is for the graph. Thinking of them as doors that open different places explains why you combine them.

Even for the same RotationSpeed, the specifier for editing in details and the one for reading in the graph are separate
Details-panel specifierWhere you can edit
EditAnywhereThe class defaults and instances placed in a level
EditDefaultsOnlyThe class defaults only
EditInstanceOnlyInstances placed in a level only
VisibleAnywhereDisplayed for inspection only
Graph-side specifierWhat you can do in Blueprint
BlueprintReadOnlyRead it with Get
BlueprintReadWriteRead with Get and overwrite with Set

Here we chose "tune the speed while authoring and do not let it be rewritten at runtime." Search for Rotation Speed in the graph and Get is available while a Set that changes the value directly is not. Category="Rotation" is a heading that groups related items.

Select BP_ItemSlow in the level and set Rotation Speed = 180 on just that instance and it takes 2 seconds per turn. Other instances and BP_ItemSlow's Class Defaults stay at 90. After trying it, use the reset arrow next to the value to restore the default.

MeshComponent's VisibleAnywhere means you cannot swap the referenced part itself for a different one. That is separate from selecting that part and adjusting its Static Mesh and Scale, so the appearance settings above still work.

Sponsored

Calling your own function from a node to pause briefly

We call the C++ SetItemSpinning from BP_ItemSlow. When it runs, the prop "spins 2 seconds → stops 1 second → keeps spinning again." BP_ItemFast and BP_ItemStill stay as they are.

In BP_ItemSlow's Event Graph, connect the following white lines from Event BeginPlay. If a BeginPlay already exists, use it.

  1. Connect to a Delay (Duration = 2.0).
  2. From Completed, call "Set Item Spinning" with Enabled set to false.
  3. Continue to another Delay (Duration = 1.0).
  4. From Completed, call Set Item Spinning again with Enabled set to true.
From BeginPlay, waiting 2 seconds and passing false to your Set Item Spinning

After stopping, the same function resumes it.

Continuing from the stop, waiting 1 second and passing true to the same function to resume

The A in the two diagrams marks the continuing white line. You do not create a node called A. Set Item Spinning's Target is Self, this BP_ItemSlow itself. To stop a different prop, you must pass that prop as Target.

Enabled corresponds to the C++ argument bEnabled. Blueprint displays the name without the b. Unchecked is false and checked is true. Passing false makes bSpinning false and skips the rotation inside Tick. Passing true spins it again.

Compile, save, Play, and confirm it stops 2 seconds after the start and starts moving again 1 second later. Change the Delay's 2.0 to 5.0 and the time until it stops changes too. Because C++ handles "how to stop" and Blueprint handles "when to stop," the timing can be tuned with nodes alone.

If the function is not in the search, check whether UFUNCTION has BlueprintCallable, whether the C++ build succeeded, and whether BP_ItemSlow's parent is RotatingItem. Choose the Set Item Spinning you created rather than a node that Sets bSpinning directly.

Applying changes: builds and Live Coding

Once comfortable, you can apply small C++ changes with Live Coding. It builds C++ while UE stays open and takes changes into the running program. With it enabled, press Ctrl + Alt + F11 and confirm success in the Live Coding window.

Try small in-function changes with Live Coding, and close and build for structural or default changes
What you changeHow to proceed early on
The BP's rotation speed or DelayCompile and save the BP, then Play
Calculation inside a .cpp functionApply with Live Coding and check the motion
Adding or changing variables, functions, or the parent classClose UE, build with Development Editor, and reopen
Parts and defaults in the constructorClose UE, build, and check on a new instance too

Live Coding does have a mechanism for handling class structure changes, so "the .h can never be applied" is not a limitation. We standardize on closing and building after structural changes here to make it easy to judge whether your first change took effect.

Also, even after fixing a C++ default, values overridden in child Blueprints or placed instances may remain. Before concluding "the build failed," also check where the value is being set.

When it doesn't work

SymptomWhere to check
The build failsThe first error in Output, the API macro name, file names, the .generated.h include order, whether UE is still open
It isn't in C++ ClassesBuild success, reopening the project, Show C++ Classes
The prop isn't visibleThe Static Mesh assignment, Scale, placement, camera direction
It doesn't spinWhether Rotation Speed is 0, Movable, Tick enabled, whether Spinning is true
Speed differs after changing the valueWhether you edited a different child BP, or overrode it on a placed instance
It doesn't stop after 2 secondsThe white line from Event BeginPlay, Enabled = false, Target = Self
It doesn't resumeThe second Delay's Completed, Enabled = true

Bonus: useful things to know next

References to parts, and TObjectPtr

TObjectPtr<UStaticMeshComponent> is "a variable pointing at the display part you created." Rather than rebuilding the part each time, you designate the same part from MeshComponent. -> is used to call features on that reference.

When holding UObject-derived objects in member variables, using a TObjectPtr with UPROPERTY lets UE track that reference. That is also relevant to garbage collection, which reclaims unneeded objects. Learning the form of keeping a reference to a part, as in this example, is a good start.

Reading values from functions, and delegating logic to Blueprint

Besides the BlueprintCallable used here, UFUNCTION has these specifiers.

SpecifierWhen to use it
BlueprintPureReturns a computed result without changing values. No white exec line
BlueprintImplementableEventThe body of logic C++ calls is built in a child Blueprint

If you want a "flash when the rotation stops" effect that varies per child, for example, you can extend to deciding the call timing in C++ and leaving the effect to Blueprint. For now, note with Callable how a C++ function becomes a node.

Before extending this to existing Blueprints

Besides creating new children as we did, you can also change an existing Blueprint's parent. But since you have to confirm the handling of same-named variables and defaults, try it on a copy first. There are also ways to split shared parts into a Component, or to start using C++ from a Data Asset type.

Spin one prop, change a value, and stop it from a node, and you have made a full loop between C++ and Blueprint. What to put where for easier authoring is covered in dividing work between Blueprint and C++.

Summary

  • Your first C++ class declares in .h and writes the body in .cpp
  • UCLASS, UPROPERTY, and UFUNCTION are the markers that make things visible to UE
  • Values with EditAnywhere can be changed from a child Blueprint's details panel
  • Functions with BlueprintCallable can be called as nodes

The question before writing is "do I want to touch this value or logic from the Blueprint side?" If you do, mark it with a macro.

To dig into dividing responsibility, go to Blueprint versus C++; the entry point for splitting features in C++ is in Subsystems.

References: C++ Class Wizard, UProperties, UFunctions, Compiling, Live Coding.

Unreal Engine Notes in this section98