Unity / C#
Advanced
Unity 2021.3+ / Unity 6
인벤토리 및 타일 배치 검사를 위한 64비트 비트마스크(Bitmask) 연산
다차원 배열 2중 루프 순회를 단일 ulong 비트 연산(AND, OR, Shift)으로 치환하여 O(1) 복잡도로 오버랩과 경계를 검사하는 그리드 최적화 기법.
#Unity #C# #Bitmask #Optimization #Inventory
핵심 개념타일 인벤토리(예: 레지던트 이블, 타르코프류)에서 8×8 슬롯의 점유 상태를
bool[8,8] 배열로 검사하면 매 마우스 드래그 프레임마다 반복문이 돕니다. 이를 하나의 ulong(64비트 정수)으로 압축하면 단 한 번의 비트 AND (&) 연산으로 충돌 여부를 O(1)에 판정할 수 있습니다.1. 비트마스크 그리드 배치 엔진
public class BitmaskInventoryGrid
{
private ulong _occupiedMask = 0UL; // 8x8 = 64개 슬롯
// x, y 좌표를 0~63 비트 인덱스로 변환
private static int ToBitIndex(int x, int y) => y * 8 + x;
/// <summary>
/// 아이템 모양 마스크를 (targetX, targetY)에 배치 가능한지 O(1) 검사합니다.
/// </summary>
public bool CanPlace(ulong itemMask, int targetX, int targetY, int itemWidth, int itemHeight)
{
// 1. 그리드 경계 검사
if (targetX < 0 || targetY < 0 || targetX + itemWidth > 8 || targetY + itemHeight > 8)
return false;
// 2. 비트 시프트로 위치 이동
int shift = ToBitIndex(targetX, targetY);
ulong shiftedItemMask = itemMask << shift;
// 3. 중복 점유 검사 (AND 연산 결과가 0이어야 빈 자리)
return (_occupiedMask & shiftedItemMask) == 0UL;
}
/// <summary>
/// 아이템을 그리드에 배치하고 마스크를 갱신합니다.
/// </summary>
public void Place(ulong itemMask, int targetX, int targetY)
{
int shift = ToBitIndex(targetX, targetY);
_occupiedMask |= (itemMask << shift);
}
/// <summary>
/// 아이템을 그리드에서 제거합니다.
/// </summary>
public void Remove(ulong itemMask, int targetX, int targetY)
{
int shift = ToBitIndex(targetX, targetY);
_occupiedMask &= ~(itemMask << shift);
}
}
2. 아이템 비트마스크 정의 예시
public static class ItemShapePresets
{
// 2x2 정사각형 아이템
// Row 0: 1 1 0 0 0 0 0 0 (0b00000011)
// Row 1: 1 1 0 0 0 0 0 0 (0b00000011 << 8)
public const ulong Shape2x2 = 0x0303UL;
// 1x3 세로 긴 막대 아이템
// Row 0: 1, Row 1: 1, Row 2: 1
public const ulong Shape1x3 = 0x010101UL;
// L자형 아이템 (2x3)
public const ulong ShapeL = 0x010103UL;
}