ゲームデータについて(1)概要

ゲームが参照するデータの実装について

例えばあなたがRPGを作りたいとして、手始めに敵モンスターのデータを実装したいとします。
最もシンプルな実装方法として思い浮かぶのは、以下のようにソースに直接定義してしまう方法でしょうか。

public struct MonsterData
{
    private string name;
    private int hp;
    private int mp;
    private int attack;
    private int defense;

    public MonsterData( string name, int hp, int mp, int attack, int defense)
    {
        this.name = name;
        this.hp = hp;
        this.mp = mp;
        this.attack = attack;
        this.defense= defense;
    }
}

public class GameData
{
    MonsterData[] monsterDataArray =
    {
        new MonsterData( "モンスター1", 10, 10, 10, 10 ),
        new MonsterData( "モンスター2", 20, 20, 20, 20 ),
        new MonsterData( "モンスター3", 30, 30, 30, 30 ),
    };
}

確かにシンプルですが、このままではモンスターのステータスの数値を変更するたびにコンパイルする必要があります。
これらのデータを外部ファイルとしてソースの外に出してしまえば、調整する際はそのファイルを更新するだけで済むので、コンパイルで時間を無駄にすることを回避できます。
また、開発メンバーが複数いて、データの調整の担当者とデータ周りのソースコードの担当者が別であれば、両者が同一ファイルを編集することを避けることにもなります。
ゲームが参照する各種データをゲームデータと呼ぶことにして、ゲームデータの管理の手法についてこれからいくつかの記事に分けて簡単に説明したいと思います。

ゲームデータの区分

ゲームデータはその性質に応じて別々に扱うことが望ましいです。
可変か固定かという区分と数値かテキストかという区分について考えていきます。

可変か固定か

ゲームを通じて変化しないデータを固定データ、ゲームの進行によって変化するデータを可変データとします。
例えば味方キャラクターが成長してステータス値が変化する仕様があるのであれば、それらは可変データとして扱います。
一方で敵モンスターには成長する仕様がなければ固定データとして扱った方がよいでしょう。
また、味方キャラクターのデータでも成長前の初期ステータス値に関しては不変なので、これについては固定データとして扱った方が便利かも知れません。
その場合、可変データとしてのキャラクターデータ(現在ステータス)を初期化する際に固定データとしてのキャラクターデータ(初期ステータス)を参照するという形になります。
このように同じオブジェクトに関連するデータでも固定データと可変データとして別々に扱われることがあります。

数値か文字列か

キャラクターやモンスターの名前は当然文字列として扱うことになりますが、文字列データは数値データとは別に管理した方がよいです。
理由としては、まず文字列データには独自の特殊処理を実装する必要がある点が挙げられます。
システムメッセージなどに見られる

"[キャラクター名]は[アイテム名]を手に入れた。"

といった、ゲームの状況に応じて特定の文字列に差し替える処理がこれに当たります。
また、将来的に外国語版を作成するのであれば翻訳が必要な文字列データが一か所にまとまっていた方が何かと都合がいいでしょう。
これらの理由から文字列データを数値データとは別に管理していきます。

開発環境について

以降の記事では以下の環境を利用してゲームデータの実装方法について説明していく予定です。

Unity 2021.3.8
Visual Studio 2019