How to combine enum bytes and bitmasks?

As I started to rely more and more on enums, I quickly realized that I was starting to duplicate a lot of concepts.
For instance a character’s EProfession could be:

  • Doctor
  • Artist
  • Politician

On the other hand a club EVIPAccess could be for:

  • None
  • Doctors
  • Artists
  • Politicians
  • All

It started to feel a bit off that I had to create two distinct enums simply because I needed a “None” and an “All” concept. Moreover this was still limited as we might have to express that the VIP access is for both doctors and politicians, not artists.

I thought that using enums as bitmasks would be the perfect solution to this problem, nevertheless I was quickly disappointed when I realized that bitwise operations like (A & B == A) between the enum bytes and their bitmask form would not return the expected results.

After looking into the values it started to make sense. Bytes values were like this:

  • Doctor = 0
  • Artist = 1
  • Politician = 2

While bitmasks values were like that:

  • Doctor = 1
  • Artist = 2
  • Politician = 4

No wonder why the bitwise operations did not work. In an intent to not go back to my initial unsatisfying solution, I am turning to you guys to figure out if is possible to setup things in a way that allows to use enums as bytes in combination with their bitmask form. I think that would make my code both cleaner and more optimized.

Thanks.

You can simply set your enum values to match your bitmask. So for example

UENUM()
enum class EProfession{
 Doctor = 1,
 Artist = 2,
 Politician = 4,
 ....
 PoolPartyPopstar = 128
}

should work.

What exactly is the input to the Make Bitmask node? What value is that “Doctor”. Can you please show the code where you defined it?

You might also try to convert the bitmask to byte first, maybe the text format handles byte and bitmask differently.

I did try this. For instance:

UENUM(BlueprintType, meta = (Bitflags))
enum class EProfession : uint8
{
	Doctor = 1,
	Artist = 2,
	Politician = 4
};
ENUM_CLASS_FLAGS(EProfession)

But when running the following BP the result are still not matching.

It will print “1 - 2”.

I think it is because of how the bytes are turned into a bitmask. Regardless of what they are they will be shifted.

So I guess there two alternatives. The first one is to declare two enums. One for using as bytes and the other one to use as bitmask. The second solution is to always transform your bytes before you compare them to bit flags. Essentially shifting (0, 1, 2) to (1, 2, 4).

I am showing the C++ code for the enum on my post. I am not sure what you mean.