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.
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.
- What we split between C++ and Blueprint here
- Preparation: creating your first C++ class
- Writing the code: a rotating Actor foundation
- The three macros: what they tell UE
- Build it and spin it in a child Blueprint
- Edit and Read: separating where you edit
- Calling your own function from a node to pause briefly
- Applying changes: builds and Live Coding
- Bonus: useful things to know next
- Summary
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.

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.
| Responsibility | What we write here |
|---|---|
| The C++ parent | Rotate a little each frame. Provide a switch for spinning and stopping |
| The child Blueprint | Choose the look and speed. Build the "stop after N seconds" with nodes |

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..."
- Choose "Actor" as the parent class and press "Next."
- Name it
RotatingItem. Do not add a leading A. - 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.
- 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.
| File | Role |
|---|---|
| .h: the header | Declares the variables this class holds and the functions callable |
| .cpp: the source | Writes what actually happens when a function is called |

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."

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.
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.

| The notation here | What 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.
| Notation | What it means here |
|---|---|
: public AActor | Inherits Actor's capabilities |
public: / protected: | C++ access scope. Separates functions used from outside from members used by this class and children |
float / bool | A type holding decimals / a type holding true and false |
90.0f | 90 as a float. The trailing f marks the type |
void | The 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.
- Save both files in Visual Studio. Confirm UE is closed.
- Set the configuration to "Development Editor" and the platform to "Win64."
- Right-click the game project CppFirstStep in Solution Explorer and run "Build."
- When the Output shows a successful build, open CppFirstStep.uproject.

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 work | Setting |
|---|---|
| Components' MeshComponent → Static Mesh | Cube from Engine's BasicShapes |
| MeshComponent → Transform Scale | Around X=0.35, Y=0.6, Z=0.2 |
| MeshComponent → Mobility | Confirm it is Movable |
| Class Defaults → Rotation | Rotation 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 Blueprint | Rotation Speed | Expected motion |
|---|---|---|
| BP_ItemSlow | 90 | One turn in 4 seconds |
| BP_ItemFast | 360 | One turn in 1 second |
| BP_ItemStill | 0 | Stays 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.

| Details-panel specifier | Where you can edit |
|---|---|
| EditAnywhere | The class defaults and instances placed in a level |
| EditDefaultsOnly | The class defaults only |
| EditInstanceOnly | Instances placed in a level only |
| VisibleAnywhere | Displayed for inspection only |
| Graph-side specifier | What you can do in Blueprint |
|---|---|
| BlueprintReadOnly | Read it with Get |
| BlueprintReadWrite | Read 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.
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.
- Connect to a Delay (Duration = 2.0).
- From Completed, call "Set Item Spinning" with Enabled set to false.
- Continue to another Delay (Duration = 1.0).
- From Completed, call Set Item Spinning again with Enabled set to true.

After stopping, the same function resumes it.

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.

| What you change | How to proceed early on |
|---|---|
| The BP's rotation speed or Delay | Compile and save the BP, then Play |
| Calculation inside a .cpp function | Apply with Live Coding and check the motion |
| Adding or changing variables, functions, or the parent class | Close UE, build with Development Editor, and reopen |
| Parts and defaults in the constructor | Close 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
| Symptom | Where to check |
|---|---|
| The build fails | The 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++ Classes | Build success, reopening the project, Show C++ Classes |
| The prop isn't visible | The Static Mesh assignment, Scale, placement, camera direction |
| It doesn't spin | Whether Rotation Speed is 0, Movable, Tick enabled, whether Spinning is true |
| Speed differs after changing the value | Whether you edited a different child BP, or overrode it on a placed instance |
| It doesn't stop after 2 seconds | The white line from Event BeginPlay, Enabled = false, Target = Self |
| It doesn't resume | The 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.
| Specifier | When to use it |
|---|---|
| BlueprintPure | Returns a computed result without changing values. No white exec line |
| BlueprintImplementableEvent | The 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
.hand writes the body in.cpp UCLASS,UPROPERTY, andUFUNCTIONare the markers that make things visible to UE- Values with
EditAnywherecan be changed from a child Blueprint's details panel - Functions with
BlueprintCallablecan 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.