Coding conventions for Unreal Engine 4 for C++, Blueprint and Python

Project Setup
Assets
Blueprint
C++
Python

View the Project on GitHub JonasReich/OpenUnrealConventions

Home / C++ / Naming

C++ Naming Conventions

File Names

Capitalization

Type Prefixes and Suffixes

Namespaces

Starting with UE5, Epic has renamed a lot of internal namespaces. We encourage following this pattern that is based on those new namespaces:

// General pattern
namespace GameOrPlugin::Module::Private::Foo::Bar {}

The elements have the following meanings:

Examples

// UE tuple implementation details. In UE4 this was called UE4Tuple_Private
namespace UE::Core::Private::Tuple {}

// Online plugins/modules from UE engine code. This contains types like FOnlineServicesRegistry.
namespace UE::Online {}

// Implementation details of UE::Online namespace members
namespace UE::Online::Private {}

// Array utility functions from Runtime module of 'Open Unreal Utilities' plugin
namespace OUU::Runtime::ArrayUtils {}

// Game project namespace for 'PuzzlePlatformer' game
namespace PuzzlePlatformer{}

Template Parameters

Type Aliases

Type aliases defined via typedefs or using declarations follow the regular type naming conventions with some exceptions / addendums

Field Names

// good
bool bIsPendingDestruction;
FSkin Skin;

// bad
bool IsOutThere;          // missing prefix
bool bPendingDestruction; // missing verb

Shadowing

Shadowed fields/variables are not allowed. MSVC allows variables to be shadowed from an outer scope, but GCC will not allow this, with good reason: It makes references ambiguous to a reader and hides mistakes.

For example, there are four variables with the name Count in this member function:

int32 Count = 42;

class FSomeClass
{
public:
    void Func(const int32 Count)
    {
        for (int32 Count = 0; Count != 10; ++Count)
        {
            // Use Count
        }
    }

private:
    int32 Count = 1000;
};

Functions

Function Parameters

Parameters that are passed in or in and out should be prefixed with In or InOut respectively.

bool Trace(FHitResult& OutHitResult);

When calling those functions, you should use the OUT macro to mark parameters that are passed by reference and initialized by the function:

FHitResult HitResult;
Foo->Trace(OUT HitResult);

Events and Delegates

The following rules apply to all types of delegates in Unreal C++ (single cast delegate, multicast delegates, dynamic multicast delegates and events).

Example (Functions, Events, Delegates)

To demonstrate the result of the conventions above, take the following practical example of commonly needed functions/events in a game character. Please note that the functions are written inline and some boilerplate code is omitted for brevity.

class AFooCharacter : public ACharacter
{
public:
    // Notify external objects about the character being killed
    FKillEvent OnKilled;

    // The only instance where a function may be called On...
    // is one that exposes a delegate.
    FSimpleMulticastDelegate& OnDamageReceived()
    {
        return DamageReceivedEvent;
    }

    // Alternative: Expose the event via function that takes in a callback.
    // This has the advantage of not exposing internal state.
    // This pattern is most commonly seen in Slate events.
    void OnDamageReceived(const FSimpleDelegate& InCallback)
    {
        DamageReceivedEvent.Add(InCallback);
    }

protected:
    // Called Handle...
    // -> we immediately know this is caused from an external event
    // most likely on a different object
    void HandleComponentHit(float Velocity)
    {
        // calulate damage from hit
        // [...]
        Server_DealDamage(Damage);
    }

    UFUNCTION(Server)
    void Server_DealDamage(float Damage)
    {
        float HealthBefore = Health;
        Health -= Damage;
        OnDamageReceived.Broadcast();
        if (Health <= 0 && HealthBefore > 0)
        {
            Kill(Damage);
        }
    }

    // Kills this character
    // Active verb -> not an event handler, not an event
    void Kill(float Damage)
    {
        // [...]
        Multicast_NativeHandleKilled();
    }

    // Event handler from an own event.
    // Can either be bound to the delegate object or invoked explicitly (this is the case here).
    // To differentiate native and Blueprint functions, this one is prefixed with Native.
    //
    // Note that the Handle and Native prefixes are combined with the Multicast_ prefix.
    // Priority of prefixes is always:
    // - 1: Net (Server_, Client_ Multicast_, OnRep_)
    // - 2: BP/C++ (Blueprint, Native)
    // - 3: Delegate (Handle)
    UFUNCTION(Multicast)
    void Multicast_NativeHandleKilled()
    {
        TriggerRagdoll(Damage);
        PlayAnimation(GetDeathAnimation());
        // [...]
        BlueprintHandleKilled();
        OnKilled.Broadcast(Damage);
    }

    // Blueprint version of NativeHandleKilled().
    // To differentiate native and Blueprint functions, this one is prefixed with Blueprint instead.
    UFUNCTION(BlueprintImplementableEvent)
    void BlueprintHandleKilled();

    // There's no c++ version of this function, so the Blueprint prefix may be omitted.
    UFUNCTION(BlueprintImplementableEvent)
    void TriggerRagdoll(float Damage);

    // Native events cannot have different names in C++ and blueprint, because they are the SAME function.
    // Therefore it must not get any prefix.
    UFUNCTION(BlueprintNativeEvent)
    UAnimationSequence* GetDeathAnimation()
    {
        // [...]
    }

private:
    // Internal event that is exposed via OnDamageRecevied() function above.
    // No strict naming conventions, because it's not part of the API.
    // Based on samples from the engine, I would reccommend replacing the usual On prefix with and Event suffix like so:
    FSimpleMulticastDelegate DamageReceivedEvent;
}