Unity で Bit 演算を使ったフラグ管理を作ってみる


Bit 演算

 Unity では、あまり見ない?(少なくとも、僕はほとんど見たことないです。C とかハードウェアに近いシステムで見た程度。。。)ので、備忘録もかねて簡単なサンプルを作ってみたお話。

ステータス異常の管理

[Github] note-nota/BitwiseOperation

ステータス異常の状態が左のチェックボックスで表現しています。真ん中のカラムでステータス異常の追加、右側のカラムで回復の操作をそれぞれ行います。

 ステータス異常の定義は以下の enum によって行います。

StatusFlags.cs
    [Flags]
    public enum StatusFlags
    {
        None      = 0,
        Poisoned  = 1 << 0,
        Blind     = 1 << 1,
        Asleep    = 1 << 2,
        Stunned   = 1 << 3,
        Silenced  = 1 << 4,
        Paralysed = 1 << 5
    }

 ステータス異常の操作部分はこんな感じ。
状態変化が起きるときに Event 発火するように OnUpdateStatus を定義してます。

PlayerStatus.cs
        public void AddStatus(byte add)
        {
            status |= (StatusFlags)add;
            OnUpdateStatus.Invoke(status);
        }

        public void DelStatus(byte del)
        {
            status &= (StatusFlags)~del;
            OnUpdateStatus.Invoke(status);
        }

Bit 演算の説明

[Flags]

 StatusFlags クラスは [Flags] アトリビュートによって bit 処理の明示を行います。なので、わざわざ書かなくても定義さえしっかりしていれば、bit 演算でも表現されるはず。。。(試してないけど。)

OR(|), AND(&), XOR(^)

0 0 0 0 0
1 0 1 0 1
0 1 1 0 1
1 1 1 1 0

NOT(~)

 否定:ビットが逆になる。

例:単純な演算

10101 | 00111 // => 10111
10101 & 00111 // => 00101
10101 ^ 00111 // => 10010

((10101 ^ 00111) | (10101 & 00111)) == (10101 | 00111) // => true

例:追加/削除

state = 10101 // 今ある状態
add   = 00010 // 追加したい状態
del   = 00100 // 削除したい状態

// 状態の追加
state | add
10101 | 00010 // => 10111

// 状態の削除
state & ~del
10101 & ~00100
10101 & 11011 // => 10001

例:判定

state == (state | flag) あるいは flag == (state & flag)

state = 10101 // 今ある状態
flagA = 00010
flagB = 00100

// flagA の判定1
state == (state | flagA)
10101 == (10101 | 00010)
10101 == (10111) // => false

// flagA の判定2
flagA == (state & flagA)
00010 == (10101 & 00010)
00010 == (00000) // => false

// flagB の判定1
state == (state | flagB)
10101 == (10101 | 00100)
10101 == (10101) // => true

// flagB の判定2
flagB == (state & flagB)
00100 == (10101 & 00100)
00100 == (00100) // => true