public class AutoWallTileSet : ScriptableObject
{
public int id;
public string name_kr;
/// <summary>
/// bitmask 순서는 상 우 하 좌
/// 상 +1 우 +2 하 +4 좌 +8
/// </summary>
[Header("Front Wall Sprites")]
public List<Sprite> frontBaseSprites = new(16);
public List<Sprite> frontUpperSprites = new(16);
[Header("Back Wall Sprites")]
public List<Sprite> backBaseSprites = new(16);
public List<Sprite> backUpperSprites = new(16);
public Sprite GetBaseSprite(int bitmask, bool isFront)
{
var list = isFront ? frontBaseSprites : backBaseSprites;
return (bitmask >= 0 && bitmask < list.Count) ? list[bitmask] : null;
}
public Sprite GetUpperSprite(int bitmask, bool isFront)
{
var list = isFront ? frontUpperSprites : backUpperSprites;
return (bitmask >= 0 && bitmask < list.Count) ? list[bitmask] : null;
}
}
public static int CalculateWallBitmask(Tile tile, Level level)
{
int bitmask = 0;
// 순서: 상 우 하 좌
for (int i = 0; i < 4; i++)
{
Tile neighbor = level.GetAdjacentTile(tile, (FourDir)i);
if (IsWallLike(neighbor))
bitmask |= 1 << i;
}
return bitmask;
}
bitmask를 활용하여 주변 타일을 검사하여 auto tiling 시스템을 구현했다.
↑ (위): 1 << 0 = 1
→ (오른): 1 << 1 = 2
↓ (아래): 1 << 2 = 4
← (왼쪽): 1 << 3 = 8
예시:
위와 아래에 벽이 있다면 → bitmask = 1 (↑) + 4 (↓) = 5
오른쪽에만 있다면 → bitmask = 2
방향별 비트 위치:
↑: 1 << 0 → 0001
→: 1 << 1 → 0010
↓: 1 << 2 → 0100
←: 1 << 3 → 1000
for (int i = 0; i < 4; i++)
{
Tile neighbor = level.GetAdjacentTile(tile, (FourDir)i);
if (IsWallLike(neighbor))
bitmask |= (1 << i);
}
비트 연산자를 활용하면 다양한 기능을 쉽게 구현이 가능하다
비트 연산자 종류 정리표
연산자이름설명
| & | AND | 둘 다 1일 때만 1 |
| ` | ` | OR |
| ^ | XOR | 서로 다르면 1 |
| ~ | NOT | 비트 반전 (1 → 0, 0 → 1) |
| << | 왼쪽 시프트 | 비트를 왼쪽으로 밀기 (×2) |
| >> | 오른쪽 시프트 | 비트를 오른쪽으로 밀기 (÷2) |
1. & (AND) 공통된 비트 검사
int a = 0b_1100; // 12
int b = 0b_1010; // 10
int result = a & b; // 0b_1000 = 8
2. | (OR) — 비트 켜기 (추가)
int flags = 0b_0001;
flags |= 0b_0100; // flags = 0b_0101
3. ^ (XOR) — 비트 토글
int x = 0b_0101;
x ^= 0b_0010; // x = 0b_0111
x ^= 0b_0010; // 다시 x = 0b_0101
4. ~ (NOT) — 비트 반전
int x = 0b_0000_1111;
int y = ~x; // y = 0b_1111_0000 (32bit 기준으로 -16)
5. << (왼쪽 시프트)
int a = 1 << 2; // 2^2 = 4 → 0b_0100
6. >> (오른쪽 시프트)
int b = 8 >> 2; // 8 / 4 = 2 → 0b_0010
실전: 게임에서 비트 연산 활용 예
분야예시비트 연산
| 오토타일링 | 주변 타일 연결 상태 | `bitmask |
| 상태관리 | 중독/기절/무적 등 ON/OFF | `flags |
| 입력 처리 | 방향키 동시에 누르기 | inputFlags & 방향 |
| 렌더링 마스크 | 레이어 설정 | layerMask & cameraMask |
자주쓰는 패턴
// 비트 켜기
flags |= (1 << 2);
// 비트 끄기
flags &= ~(1 << 2);
// 비트 토글
flags ^= (1 << 2);
// 비트 검사
bool isSet = (flags & (1 << 2)) != 0;
정리
| a & b | 공통된 비트만 유지 |
| `a | b` |
| a ^ b | 서로 다른 비트만 유지 |
| ~a | 모든 비트 반전 |
| a << n | a를 왼쪽으로 n칸 이동 (×2ⁿ) |
| a >> n | a를 오른쪽으로 n칸 이동 (÷2ⁿ) |