How do I create a new class in Unreal Engine?

Crafting Custom Classes in Unreal Engine

11/10/2002

Rating: 4.62 (6700 votes)

Unreal Engine is a powerhouse for game development, offering both visual scripting with Blueprints and robust C++ programming. While Blueprints are fantastic for rapid prototyping and many gameplay elements, C++ classes are indispensable for complex game logic, performance-critical systems, and when you need the full power and flexibility of a compiled language. Creating a new C++ class in Unreal Engine is a fundamental step for any serious developer looking to extend the engine's capabilities and build truly unique and high-performance game features.

How do I create a new class in Unreal Engine?
Table

The Importance of C++ Classes in Unreal Engine

Before diving into the 'how-to', it's crucial to understand 'why'. C++ classes in Unreal Engine provide several significant advantages:

  • Performance: For computationally intensive tasks, C++ offers superior performance compared to Blueprints, as it compiles directly to machine code.
  • Complex Logic: C++ allows for more intricate algorithms, data structures, and lower-level system access, which can be challenging or impossible to implement efficiently in Blueprints alone.
  • Modularity and Reusability: Well-designed C++ classes can be highly modular and reusable across different projects or within various parts of the same game, promoting cleaner codebases.
  • Version Control Friendliness: C++ code integrates seamlessly with standard version control systems (like Git or Perforce), making team collaboration smoother and conflict resolution more manageable.
  • Engine Extension: Many core engine features and plugins are written in C++, and creating your own C++ classes allows you to interact with and extend these systems directly.
  • Team Collaboration: In larger teams, C++ often serves as the backbone for core gameplay mechanics and systems, while Blueprints are used for higher-level scripting by designers.

Understanding these benefits will help you decide when to opt for a C++ class over a Blueprint, often leading to a hybrid approach where C++ provides the foundation and Blueprints build on top of it.

Step-by-Step Guide: Creating Your First C++ Class

The process of creating a new C++ class in Unreal Engine is surprisingly straightforward, thanks to the integrated development environment. Follow these steps carefully to set up your custom class.

1. Launch Unreal Editor and Open Your Project

First, ensure you have your Unreal Engine project open. You can create a new project or open an existing one. Once the editor is loaded, you'll be presented with your level viewport and various panels.

2. Access the New C++ Class Wizard

There are a couple of ways to initiate the class creation process:

  • Go to the top menu bar: File > New C++ Class...
  • In the Content Browser, right-click and select New C++ Class... (This option is usually available if you have a C++ project. If not, the first method is always reliable).

Selecting this option will open the 'New C++ Class' wizard, which will guide you through the necessary choices.

3. Choose a Parent Class

The first and arguably most important decision you'll make is selecting a parent class. The parent class determines the fundamental behaviour and capabilities your new class will inherit. Unreal Engine provides a wide array of base classes to build upon, each serving a specific purpose. The wizard will present you with a list of common parent classes.

If you don't see the specific class you need, you can check the 'Show All Classes' box in the wizard to reveal a more extensive list. It's crucial to choose the most appropriate parent for your intended functionality. For instance, if you're creating an item that can be placed in the world, Actor is usually the correct choice. If you're building a player character that needs movement and input, Character is the way to go.

Common Parent Classes Explained:

Parent ClassDescriptionTypical Use Cases
UObjectThe base class for all Unreal Engine objects. It provides core functionality like garbage collection, reflection, and serialisation. It cannot be placed in a level.Game state management, utility classes, data containers, custom assets that don't need to be placed in the world.
AActorThe base class for any object that can be spawned or placed in a level. Actors can have components, transform (position, rotation, scale), and can replicate across a network.Interactable objects, pickups, projectiles, environmental elements, AI entities that don't need player input.
APawnA type of Actor that can be possessed by a PlayerController or AIController. Pawns represent the physical presence of a player or AI in the world.Vehicles, non-humanoid player characters, simple AI bots.
ACharacterA specialised type of Pawn designed for bipedal characters. It includes a CharacterMovementComponent, CapsuleComponent for collision, and built-in networking support for movement.Player characters (humanoid), complex AI characters, NPCs with advanced movement.
UActorComponentA reusable piece of functionality that can be attached to an Actor. Components allow for modular design and can be shared across multiple Actors.Health systems, inventory systems, custom movement logic, weapon handling, interaction logic.
UGameModeBase / AGameModeDefines the rules of the game, including player joining/leaving, spawning, HUD, and scoring. UGameModeBase is simpler, while AGameMode (derived from Base) offers more advanced features like session management.Defining game rules, managing player states, handling game flow (e.g., round-based games, objective completion).
APlayerControllerResponsible for possessing a Pawn or Character and handling input from a player. It acts as the interface between the player and their controlled entity.Player input processing, camera control, UI interactions specific to a player.

4. Configure Class Settings

After selecting your parent class, the wizard will prompt you for a few more details:

  • Name: This is the name of your new C++ class. Adhere to Unreal Engine's naming conventions, which typically involve a prefix (e.g., 'A' for Actor, 'U' for UObject, 'F' for Structs) followed by a descriptive name. For example, AMyCustomPickup or UInventoryComponent. Avoid spaces or special characters.
  • Path: This specifies where the new C++ header (.h) and source (.cpp) files will be created within your project's 'Source' folder. By default, it will suggest a subfolder within your project's main source directory. It's good practice to organise your classes into logical folders (e.g., ProjectName/Public/Characters, ProjectName/Private/Components).
  • Public/Private: The wizard might offer a choice for 'Public' or 'Private' folders. Generally, 'Public' headers contain declarations that can be included by other modules, while 'Private' headers and source files are for internal implementation details of your module. For most new game-specific classes, 'Public' is the common choice for the header, and 'Private' for the source file, or simply placing both in a logical folder within your module's source directory.

Once you've filled in these details, click the 'Create Class' button.

5. Compilation and IDE Opening

Upon clicking 'Create Class', Unreal Engine will perform a few actions:

  • It will generate the .h (header) and .cpp (source) files for your new class in the specified directory.
  • It will then attempt to compile your project. This process is known as 'hot reloading' if the editor is already open.
  • Finally, it will automatically open your default C++ Integrated Development Environment (IDE), typically Visual Studio on Windows or Xcode on macOS, and display the newly created files.

It's important that the compilation step completes successfully. If there are errors, you'll see messages in the Output Log within Unreal Editor. Address any compilation issues before proceeding.

Understanding the Generated Code

When your IDE opens, you'll see two new files. Let's break down what's inside them.

The Header File (YourClassName.h)

This file contains the class declaration. It defines the structure of your class, including its properties (member variables) and functions (member methods). Here's a typical structure:

#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" // Or your chosen parent class header #include "YourClassName.generated.h" UCLASS() class YOURPROJECTNAME_API AYourClassName: public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AYourClassName(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; }; 
  • #pragma once: Ensures the header file is included only once during compilation.
  • #include "CoreMinimal.h": A core include for most Unreal Engine C++ files.
  • #include "GameFramework/Actor.h": Includes the header for your chosen parent class.
  • #include "YourClassName.generated.h": This is crucial! It's a generated file created by Unreal Engine's Unreal Header Tool (UHT). It contains boilerplate code for Unreal's reflection system, allowing properties and functions to be exposed to the editor and Blueprints.
  • UCLASS(): This macro marks your class as an Unreal Engine class, making it discoverable by the UHT and the engine's reflection system. Without this, your class won't function correctly within Unreal.
  • class YOURPROJECTNAME_API AYourClassName: public AActor: This declares your class. YOURPROJECTNAME_API is a module export macro, essential for exposing your class to other modules. AYourClassName is your class name, and : public AActor indicates it inherits from AActor (or your chosen parent).
  • GENERATED_BODY(): Another essential macro. It handles various boilerplate functionalities, including reflection, type information, and garbage collection. Always include this as the first line in your class body.
  • Constructor:AYourClassName(); is the class constructor, where you'll set default values for your class's properties.
  • BeginPlay(): A virtual function called when the game starts or when the actor is spawned into the world. Ideal for initialisation logic.
  • Tick(float DeltaTime): A virtual function called every frame. Useful for continuous updates, movement, or other per-frame logic.

The Source File (YourClassName.cpp)

This file contains the implementation of your class's functions. It links to the header file and provides the actual code that executes.

#include "YourClassName.h" // Sets default values AYourClassName::AYourClassName() { // 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 AYourClassName::BeginPlay() { Super::BeginPlay(); } // Called every frame void AYourClassName::Tick(float DeltaTime) { Super::Tick(DeltaTime); } 
  • #include "YourClassName.h": Includes your class's header file.
  • Constructor Implementation: The constructor is where you set the initial state of your object. The line PrimaryActorTick.bCanEverTick = true; enables or disables the Tick() function. If your class doesn't need to update every frame, setting this to false is a performance optimisation.
  • BeginPlay() and Tick() Implementations: These are the implementations of the virtual functions declared in the header. Super::BeginPlay(); and Super::Tick(DeltaTime); are crucial calls to ensure that the parent class's versions of these functions are also executed. Always call the super implementation when overriding virtual functions unless you have a very specific reason not to.

Exposing Properties and Functions to Unreal Editor (Reflection)

One of the most powerful features of Unreal Engine's C++ is its reflection system, enabled by special macros. This allows you to expose variables and functions to the Unreal Editor, making them editable by designers and accessible from Blueprints.

UPROPERTY() Macro

Use UPROPERTY() to expose member variables (properties) to the editor. You can add specifiers inside the parentheses to control their behaviour.

UCLASS() class YOURPROJECTNAME_API AMyCustomPickup: public AActor { GENERATED_BODY() public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pickup") float RotationSpeed; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pickup") int32 CurrentPickups; }; 

Common specifiers include:

  • EditAnywhere: Property can be edited in the Details panel of the editor for instances of the class and in the Blueprint default values.
  • EditDefaultsOnly: Property can only be edited in the Blueprint default values (e.g., in the Blueprint class editor), not on placed instances.
  • EditInstanceOnly: Property can only be edited on placed instances in the level, not in Blueprint defaults.
  • VisibleAnywhere: Property is visible in the editor but not editable.
  • BlueprintReadWrite: Property can be read and written from Blueprints.
  • BlueprintReadOnly: Property can only be read from Blueprints.
  • Category = "MyCategory": Groups the property under a specific category in the Details panel.

UFUNCTION() Macro

Use UFUNCTION() to expose member functions (methods) to the editor and Blueprints.

UCLASS() class YOURPROJECTNAME_API AMyCustomPickup: public AActor { GENERATED_BODY() public: UFUNCTION(BlueprintCallable, Category = "Pickup") void CollectPickup(); UFUNCTION(BlueprintImplementableEvent, Category = "Pickup") void OnCollectedBlueprintEvent(); }; 

Common specifiers include:

  • BlueprintCallable: Function can be called from Blueprints.
  • BlueprintPure: Function can be called from Blueprints and is "pure" (has no side effects, doesn't modify object state).
  • BlueprintImplementableEvent: Declares an event that can be implemented (overridden) in Blueprints.
  • BlueprintNativeEvent: Declares an event that has a C++ implementation but can also be overridden in Blueprints.
  • Server, Client, NetMulticast: For networking replication.

After Class Creation: Using Your New Class

Once your C++ class has been created and compiled successfully, you can start using it within your project.

Finding Your Class in the Editor

If your class inherits from AActor, APawn, or ACharacter, you can find it in the 'Place Actors' panel (usually on the left side of the editor). Simply drag and drop an instance of your class into the level.

For other classes (like UActorComponent or UObject), you'll typically create them programmatically in C++ or add them as components to existing Actors/Blueprints.

Creating a Blueprint from Your C++ Class

A common workflow in Unreal Engine is to create a Blueprint class that inherits from your C++ class. This allows designers to easily extend and customise your C++ functionality using visual scripting without touching code.

To do this, right-click on your C++ class in the Content Browser (you might need to enable 'Show C++ Classes' in the Content Browser settings) and select 'Create Blueprint Class based on [YourClassName]'. This will create a new Blueprint asset that uses your C++ class as its parent.

Best Practices for C++ Class Development

  • Naming Conventions: Adhere to Unreal Engine's strict naming conventions (e.g., A prefix for Actors, U for UObjects/Components, F for Structs, T for Templates). This improves code readability and maintainability.
  • Choose the Right Parent: Always select the most appropriate and least complex parent class for your needs. Don't inherit from ACharacter if AActor suffices.
  • Modular Design: Break down complex functionality into smaller, reusable components (UActorComponent). This makes your code easier to manage, debug, and extend.
  • C++ First, Blueprint Second: Implement core, performance-critical, or complex logic in C++. Expose properties and functions to Blueprints only when necessary for designer iteration or simple gameplay scripting.
  • Use Categories: Always use the Category = "YourCategory" specifier for UPROPERTY and UFUNCTION to keep the editor's Details panel organised.
  • Comment Your Code: Clearly comment your C++ code to explain its purpose, especially for complex logic or public interfaces.
  • Regular Compilation: Compile your project frequently to catch errors early. Use the 'Compile' button in the Unreal Editor or build from your IDE.
  • Avoid Circular Dependencies: Be mindful of how your header files include each other to prevent circular dependencies, which can lead to compilation errors. Use forward declarations (e.g., class AMyOtherActor;) when possible instead of full includes.

Troubleshooting Common Issues

Even with a streamlined process, you might encounter issues. Here are some common problems and their solutions:

  • Class Not Showing in Editor: Ensure your project compiled successfully. If you added the class while the editor was open, hot-reloading might have failed. Close the editor, right-click your .uproject file, and select 'Generate Visual Studio project files', then open the solution and build from Visual Studio. Alternatively, simply restart the editor.
  • Compilation Errors: Check the 'Output Log' in Unreal Editor or the 'Error List' in your IDE. Common errors include missing semicolons, incorrect includes, typos, or forgetting UCLASS()/GENERATED_BODY()/UPROPERTY()/UFUNCTION() macros.
  • IntelliSense Issues (Visual Studio): Sometimes IntelliSense (code completion and error highlighting) can stop working correctly. Try regenerating project files (right-click .uproject > 'Generate Visual Studio project files') or cleaning/rebuilding your solution in Visual Studio. Ensure your Visual Studio installation includes the 'Game development with C++' workload.
  • Hot Reload Failed: This often happens if you've made significant changes (e.g., adding new properties with UPROPERTY, changing a class's parent). When hot reload fails, the safest bet is to close the Unreal Editor, compile your project from your IDE (Visual Studio/Xcode), and then reopen the editor.
  • Missing Required Modules: If your class uses functionality from a module not typically included (e.g., AIModule, Niagara), you'll need to add it to the PublicDependencyModuleNames array in your project's Build.cs file.

Frequently Asked Questions (FAQs)

Q: Can I change the parent class of an existing C++ class?

A: Generally, no. Changing the parent class after creation is highly discouraged and can lead to significant compilation issues and unexpected behaviour. It's almost always better to create a new class with the correct parent and migrate your code.

Q: What's the difference between a C++ class and a Blueprint class?

A: A C++ class is compiled code, offering high performance and low-level control, ideal for core systems and complex logic. A Blueprint class is a visual scripting asset built on top of C++ classes, offering rapid iteration and accessibility for designers. Blueprints compile to bytecode and are generally slower than native C++ but are much faster to prototype with. Often, a C++ class provides the foundation, and a Blueprint class extends it.

Q: Why would I use C++ over Blueprints if Blueprints are easier?

A: While Blueprints are user-friendly, C++ offers superior performance for intensive calculations, allows for more complex data structures and algorithms, provides full access to the engine's API, and is often preferred for large-scale projects due to better maintainability and version control integration for code. It's about choosing the right tool for the job.

Q: How do I delete a C++ class?

A: Deleting a C++ class requires a few steps to ensure a clean removal:

  1. Close Unreal Editor.
  2. In your IDE (e.g., Visual Studio), remove the .h and .cpp files from your project.
  3. Physically delete the .h and .cpp files from your project's 'Source' folder on disk.
  4. Delete the corresponding .generated.h file from the 'Intermediate' folder (e.g., ProjectName/Intermediate/Build/Win64/UE4Editor/Inc/ProjectName/YourClassName.generated.h).
  5. Right-click your .uproject file and select 'Generate Visual Studio project files'.
  6. Reopen your solution in the IDE and build the project.
  7. Reopen Unreal Editor.

This ensures all references are cleaned up.

Q: Can I add components to my C++ class directly in C++?

A: Yes! You can create and attach components in your class's constructor. For example, to add a static mesh component to an Actor:

AYourClassName::AYourClassName() { // Create a Static Mesh Component StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent")); RootComponent = StaticMeshComponent; // Set it as the root component // You can also attach other components // USphereComponent* SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereCollision")); // SphereComp->SetupAttachment(RootComponent); } 

Remember to declare the component as a UPROPERTY in your header file.

Conclusion

Creating C++ classes in Unreal Engine is a cornerstone of professional game development within the engine. It empowers you to write highly optimised, complex, and modular game logic that can serve as the robust foundation for your projects. While the initial setup involves understanding a few specific macros and conventions, mastering this process opens up a world of possibilities for extending Unreal Engine and crafting truly bespoke gameplay experiences. By following best practices and understanding the underlying structure, you'll be well-equipped to leverage the full power of C++ in your Unreal Engine journey.

If you want to read more articles similar to Crafting Custom Classes in Unreal Engine, you can visit the Automotive category.

Go up