BitMask Tutorial?

Im wondering if someone can help me understand bitmasks in a simple way. i’ve never used them and i tried looking at the API but i just dont understand it… I understand how to make them. I just dont understand how to USE them. I made the enum and everything. I have 2. One for faction type of my character and the other for movement calling such as attacking, dodging, sprinting, etc. I tried to use my flag in an if statement and its not working. nor do i know how to set the flag to the proper number. Any help is appreciated, thank you!
from the tutorial, this is what i came up with :
UENUM(BlueprintType, meta = (Bitflags))

enum class EMovementCallFlags : uint8

{

Dodging,

Sprinting,

Attacking,

Blocking,

};

ENUM_CLASS_FLAGS(EMovementCallFlags)
UPROPERTY(EditAnywhere, Category = “MovementCalls”, meta = (Bitmask, BitmaskEnum = “EMovementCallFlags”))

uint8 MovementCallFlags;

Bitflags aren’t UE4 specific, I’d just google for a good C++ Bit Operators tutorial and run through that. They’re simple, but rather difficult to describe in just a few lines.

As for your questions:

To turn a flag on:



MovementCallFlags |= EMovementCallFlags::Dodging;


To turn a flag off:



MovementCallFlags &= ~EMovementCallFlags::Dodging;


To test for a flag:



if (MovementCallFlags & EMovementCallFags::Dodging)
{
   // Flag is true.
}


2 Likes

@ExtraLifeMatt Hey! Thank you for replying i will definitely look this up, i appreciate it!

@ExtraLifeMatt Hi! im sorry to reopen this lol. I really dont understand bitmasking. I read things like the 0001 and what not, i tried using your calls and it works but only with for example MOvementCallFlags |= 1; (which is dodging) I understand that with the uint8 everythign is a power of 2 and so it goes 1,2,4,8 which is then 8 bits. I get all that and so that equals out to be whatever you have that check to. What i dont understand is basically the whole 0001 stuff and i dont understand why im getting this error “Invalid operands to binary expression (‘uint8’ (aka ‘unsigned char’) and ‘EMovementCallFlags’)” Unfortunately with me, if i dont understand something at all. I get stuck. I tried making EMovementCallFlags Movement; so maybe i could use Movement.dodging but that still doesnt work. Im very lost in this stuff and me reading things that breaks it down so much to the point where its overwhelming and i just dont understand it at all is so frustrating because tbh i feel stupid. Something isnt clicking lol. Anyway, any guidance will help. I guess a TLDR would be i dont understand the concept of bitmasking/flagging. I feel like once i do, they will be very powerful to use and conserve memory rather than just doing bSprinting, bdodging , bEtc. Everythign can be in one place and all work together. I also want factions and flag enums would be great for this feature! Thanks again i hope i can really grasp this D:

@ExtraLifeMatt ^

I also understand the whole MovementCallFlags << 2 so for instance the bit goes from 0001 to 0010. It shifts left 2 places, pretty much like a decimal point?
Also, how come I cant do : MovementCallFlags |= EMovementCallFlags::Sprinting;? It gives me the error :
nvalid operands to binary expression (‘uint8’ (aka ‘unsigned char’) and ‘EMovementCallFlags’)

You may have to do



MovementCallFlags |= static_cast<uint8>(EMovementCallFlags::Sprinting);


Basically force it to interpret those enums as integers. And it’s not quite like moving a decimal place, just because of how numbers are represented in memory but you have the gist of it.

@ExtraLifeMatt Thank you for verifying! Next question, is this if (MovementCallFlags & static_cast<uint8>(EMovementCallFlags::Sprinting)) basically saying if Sprinting is true then do blah? because from the code above im getting that youre setting the flag to be true not checking if its true. I tried it and my character is stuck in sprinting but i reset my flag with &=~

Yes.



if (MyValue & MyOtherValue)
{
 // Blah
}


Is just doing a binary AND between the values and is interpreted as true if the value isn’t zero, or false if it is.