UE4中的位掩碼(Bitmask)的介紹和使用

Zz傑發表於2020-10-21

簡介

環境:UE 4.25

位掩碼(Bitmask)

位掩碼是一串二進位制數(比如子網掩碼),每一位是一個Flag,表示一種狀態,一個32位的位掩碼就可以表示32種狀態的組合。如果期望使用多個bool變數共同作用與同一個地方,就可以使用位掩碼來實現。

  • 使用位掩碼是為了控制一組bool變數,用一個變數就可以表示豐富的狀態。
  • 使用列舉是為了給每個Flag命名,增強可讀性。

位操作

由於位掩碼是使用二進位制來表示一個Flag,所以最常使用的操作就是位運算:與(&)、非(~)、或(|)、異或(^)、左移(<<)和右移(>>)。
bit

藍圖位掩碼

藍圖建立位掩碼可檢視官方教程

建立位掩碼

總結一下過程可分為3步:

  1. 建立一個藍圖列舉,並將Bitmask Flags設為true
    1

  2. 在藍圖中建立一個整型變數,設定為Bitmask,最多支援32個Flags
    2

  3. 使用它
    3
    其中常用的操作為:
    • 隱式轉化為bool:判斷Bitmask中是否含有Flags。
    • 按位非(Bitwise NOT):得到一個相反的Bitmask。
    • 按位與(Bitwise AND):得到一個含有共同Flags的Bitmask。
    • 按位或(Bitwise OR):得到一個含有所有Flags的Bitmask。

使用方式示例

• 開啟Flag:
open
• 關閉Flag:
close
• 判斷是否包含Flag:
if

C++位掩碼

在C++中使用位掩碼有更大的自由度。可以使用int32、int64、uint32等表示掩碼,而藍圖只支援int32。同時,表示Bitflags的列舉型別也可以使用uint32、uint64等,而藍圖只支援uint8。
Bitmask常用的操作(變數作為示範):

	//int32 MyBitmask = 3;
	//int32 MyFlag = 1;
	MyBitmask |= MyFlag; //開啟Flag
	MyBitmask &= ~MyFlag; //關閉Flag
	if (MyBitmask & MyFlag) { /*Do something*/ }//判斷Flag是否開啟

方式一

可以利用左移操作設定列舉值,使得列舉變數對應的值與它的Bitmask的Flag值是一樣的。

UENUM(meta = (Bitflags))
enum class EMyTypeEnum :uint32
{
	Type1 = (1 << 0),
	Type2 = (1 << 1),
	Type3 = (1 << 2),
	Type4 = (1 << 3),
	Type5 = (1 << 4),
	Type6 = (1 << 5)
};
	UPROPERTY(EditAnywhere, BlueprintReadWrite,meta = (Bitmask,BitmaskEnum = "EMyTypeEnum"))
		int32 MyTypeBitmask;

判斷Bitmask中是否包含列舉對應的Flag(直接轉化即可得到Flag值):

	if (MyTypeBitmask & static_cast<uint32>(EMyTypeEnum::Type2))
	{
		//Do something
	}

方式二

如果需要同時在C++和藍圖中都獲得良好的體驗,則需要新增函式或巨集來獲得列舉對應正確的Bitmask值。
使用巨集從正常順序的列舉值得到Flag值:

#define TOFLAG(Enum) (1 << static_cast<uint8>(Enum))

藍圖和C++都可以使用該列舉作為Bitflags:

UENUM(BlueprintType, meta = (Bitflags))
enum class EMyTypeEnum :uint8
{
	Type1, //= 0
	Type2, //= 1
	Type3, //= 2
	Type4, //= 3
	Type5, //= 4
	Type6  //= 5
};
	UPROPERTY(EditAnywhere, BlueprintReadWrite,meta = (Bitmask,BitmaskEnum = "EMyTypeEnum"))
		int32 MyTypeBitmask;

判斷Bitmask中是否包含列舉對應的Flag(使用巨集得到Flag值)

	if (MyTypeBitmask & TOFLAG(EMyTypeEnum::Type2))
	{
		//Do something
	}

相關文章