Bitmask / Bitflag Enums

C++ Usage of Bitmasks and Bitflags

Updated 6 months ago Edit Page Revisions

Overview

Bitmask enums are a way of organizing flags. Like having a collection of booleans without having to keep track of a dozen different variables. They are fast and compact, so generally good for network related data.

There is a little setup involved, but the technical details are generally hidden in blueprints, and the default interface for flags and bitmasks is very friendly, so that makes it attractive.

Quick & Shitty Overview of Flags and Masks

int32 variables are made up of 32 bits. That is, 32 positions for either a 1 or a 0. The value of each bit in an integer can be looked at individually and treated like a boolean. The values work as outlined below

// General flags & bits!
1: 0001
2: 0010
4: 0100
8: 1000

// Example
5: 0101 -- Hey, both 1 and 4 are in there!

Enum Creation

Some .h file

UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class ECharacterQualities: uint8
{
	NONE	   = 0 UMETA(Hidden),
	TALL	   = 1 << 0,
	DARK	   = 1 << 1,
	HANDSOME   = 1 << 2,
	PROGRAMMER = 1 << 3,
};
ENUM_CLASS_FLAGS(ECharacterQualities);

Usage

... as a value

Some implementing .h file

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (Bitmask, BitmaskEnum = ECharacterQualities))
int32 QualityFlags = 0;

... in a method

Checking for a single flag would just be doing an 'and' operation on the value in question

UFUNCTION(BlueprintCallable)
bool IsTall() const
{
    return QualityFlags & ECharacterQualities::TALL;
}

... as a Blueprint Variable

If you want to use this enum from a blueprint, rather than creating the variable as enum, you first create it as an integer, mark it as a bitmask, then select which enum type it is from the details panel.

... as a Blueprint Parameter

If you want a blueprint method to make this call, you can do the following

// SomeDude.h
UFUNCTION(BlueprintCallable)
bool IsMatch(UPARAM(meta = (Bitmask, BitmaskEnum = EAnimDescriptorFlags)) int32 Bitmask);

// SomeDude.cpp
bool USomeDude::IsMatch(const int32 Bitmask)
{
    return Bitmask & QualityFlags == Bitmask;
}

Would wind up looking like this