【C#】ゲーム開発における enum を用いたビット演算の活用方法

【C#】ゲーム開発におけるenumを用いたビット演算の活用方法

はじめに

この記事では、ゲーム開発における enum を用いたビット演算の活用方法を紹介します。そもそもビット演算とは何かといった解説は省略します。

ビット演算が役立つパターン

どのような時にビット演算が役立つか事例を交えて説明します。

例えばプレイヤーに複数のステータス情報を持たせたい場合を想定します。
以下のコードでは、攻撃力アップ状態を表す isAttackUp、毒状態を表す isPoison、眠り状態を表す isSleeping をPlayerクラスにそれぞれ変数として持っています。

public class Player
{
    private bool isAttackUp;
    private bool isPoison;
    private bool isSleeping;

    // 省略
}

仕様の追加で氷状態や火傷状態のステータス情報が必要になると、その度に変数がどんどん増えていき、管理方法としてあまり良くない状態となってきます。

ここでビット演算を活用します。
ビット演算を使うことで、これら複数のステータス情報をまとめて一つの変数で管理できるようになります。

以下のコードでは enum にステータスのタイプを定義し、playerStatus をステータス情報を管理する変数としています。 enum に Flags属性を追加することで列挙体をビットとして扱えるようにして、シフト演算(<<)で各ステータスのビットを定義しています。

public class Player
{
    private PlayerStatus.Type status;
}

public class PlayerStatus
{
    [Flags]
    public enum Type
    {
        None        = 0,
        AttackUp    = 1,
        Poison      = 1 << 1,
        Sleeping    = 1 << 2,
    }
}

ビットフラグの追加

ステータスを追加したい場合は、| 演算子(OR 演算子)を使います。

// 毒状態を追加
status = status | PlayerStatus.Type.Poison;
// または
status |= PlayerStatus.Type.Poison;

Debug.Log(status.HasFlag(PlayerStatus.Type.Poison));
// -> True

ビットフラグの削除

ステータスを削除したい場合は、~ 演算子(反転演算子)を使います。

// 睡眠状態を削除
status = status & ~PlayerStatus.Type.Sleeping;
// または
status &= ~PlayerStatus.Type.Sleeping;

Debug.Log(status.HasFlag(PlayerStatus.Type.Sleeping));
// -> False

ビットフラグの追加や削除を行うことで、1つのフラグで複数のステータス状態を管理できるようになりました。

status = PlayerStatus.Type.None;
Debug.LogError(status);
// -> None

// 毒状態を追加
status |= PlayerStatus.Type.Poison;
Debug.LogError(status);
// -> Poison

// 睡眠状態を追加
status |= PlayerStatus.Type.Sleeping;
Debug.LogError(status);
// -> Poison, Sleeping

// 睡眠状態を削除
status &= ~PlayerStatus.Type.Sleeping;
Debug.LogError(status);
// -> Poison

おわりに

ゲーム開発におけるビット演算の活用方法を紹介しました。
この他にも様々な活用方法があるので、使ってなかった方はぜひビット演算を活用してみて下さい。