読者です 読者をやめる 読者になる 読者になる

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

Unityでゲームのフラグ管理

Unity ゲームの作り方・チュートリアル・サンプル スクリプト

ちょっと聞かれたのでUnityでフラグ管理について。
これの続きです。
tsubakit1.hateblo.jp


フラグ管理と聞けば面倒なように聞こえるが、要するに何処からでもアクセス出来るようなクラスに値を持たせておくだけでOKだ。後はifやswitchで必要になった時に確認すれば良い。

色々考えたが、やはりシンプルなDictionaryで十分かなと思った。

Dictionaryはキーを指定すると値を取得できるコレクション(値をたくさん持ってるアレ)だ。これを使用すると、フラグ名を指定して値を取得したり、逆に上書きしたりする事ができる。

using System.Collections.Generic;
using UnityEngine;

public class FlagManager : MonoBehaviour {
    public Dictionary<stringobjectflagDictionary = 
        new Dictionary<stringobject>();
}

呼び出しはこんな感じ。

using UnityEngine;
using System.Collections;

public class FlagCaller : MonoBehaviour 
{
    private FlagManager flagManager;

    void Start () 
    {
        flagManager = GetComponent<FlagManager>();



        flagManager.flagDictionary["CHECK_1"] = true; // CHECK_1にTRUEを登録
        flagManager.flagDictionary["CHECK_1_COUNT"] = 120; // CHECK_1_COUNTに120をry
    }
    
    void Update () 
    {
        Debug.Log( (bool)flagManager.flagDictionary["CHECK_1"] );        // 120
        Debug.Log( (int)flagManager.flagDictionary["CHECK_1_COUNT"] );    // TRUE
    }
}


ただしこの手法には普通にクラスが変数を持つのと比較し便利な点と注意すべき点が有る。

まず便利な点だが、文字列や値からキーを指定することが出来る。つまり、クラスに変数を定義しなくとも値を設定・取得できるので、手間が減る。この為、ちょっとフラグを足す・減らすのが単純作業を見ると楽にできる。

注意すべき点だがメリットがまんまデメリットになる。つまり、キーの指定が文字列なので間違った文字列を指定した時に問題に気づきにくい。特に大文字小文字やスペルミス等で間違っているケースは割と多い。また、フラグの数を減らす際にも文字列で検索しなくてはいけないため、使用頻度が多いフラグは一苦労だ。
もう一点ある。パフォーマンスが変数を普通に定義した物より悪い。要するに値を検索するコストが発生するので、単純に変数を定義した物よりも若干高コストとなる。ちなみにキー名+値のメモリを喰うので値のみの場合と比較して若干メモリ消費が上がるが、この程度の誤差は重要ではない。

こう見ると変数の方が良いように感じるかもしれないが、1点補足がある。Dictionaryを使ったほうがメタデータでフラグを管理する場合に制御が楽という事だ。

Dictionaryを使わず記述するとこんな感じ。

using System.Collections.Generic;
using UnityEngine;

public class FlagManager : MonoBehaviour {
    public bool check_1;
    public int check_1_count;
}

using UnityEngine;
using System.Collections;

public class FlagCaller : MonoBehaviour 
{
    private FlagManager flagManager;

    void Start () 
    {
        flagManager = GetComponent<FlagManager>();

        flagManager.check_1 = true;
        flagManager.check_1_count = 120;
    }
    
    void Update () 
    {
        Debug.LogflagManager.check_1 );        // 120
        Debug.LogflagManager.check_1_count );    // TRUE
    }
}


こう見ると変数の方が良いように感じるかもしれないが、1点補足がある。Dictionaryを使ったほうがメタデータでフラグを管理する場合に制御が楽という事だ。
例えばフラグを管理するようなシステムの場合、ノベルゲームやアドベンチャーゲームRPG等が上がる。これらのシステムは大抵の場合コードに直接処理を記述したりせず、外部のテキストデータやメタデータで管理する。

そういった処理を行った場合にクラスの変数を直接フラグに使用すると、変数とメタデータの値を紐付けなければならず、面倒なことになる。積極的なフラグ制御を行う脱出ゲーム等の場合は尚更だ。

どちらを使うかは、作る規模によって選択するのも良さそうだ。

なおクラス+値で管理した方が作るの自体は楽なので、よくわからないならクラスをお勧め。実装自体がシンプルだし、Inspectorから値を確認する事も出来る。(実際はSceneもメタデータの一種だと思う)

次の「どこからでもアクセス可能」は凄く長くなったので、一旦切る