imog

主にUnityとかの事を書いています

UnityのInspectorはDataStoreの一種かなと思った

ふと思ったのでメモ

今趣味で作ってるゲームはMVPで書いてるけど、ModelにDataStoreの概念があります。

public interface IDataStore<TEntity> : where TEntity : IEntity {
    TEntity ToEntity();
}

持ってるデータからEntityを生成してくれる君です。このデータはサーバからJSONで来てるかもしれないし、ScriptableObjectやAssetBundleかもしれないけどインタフェースで持つのであまり気にする必要はありません。

DataStoreがあるのでEntityはUnityの世界から切り離されていい感じになります。

public class Life : IEntity {
    public readonly int max;
    public int Current { get; private set; }
    public float Ratio { get { return max / Current * 100F; } }
}

雑なライフポイント的なEntityですが、ここにUnityの概念はありません。

一方で、Unityはインスペクタから値を設定できる機能が便利です。ライフポイントとかはまさにインスペクタからチョチョイと弄りたくなるようなやつです。 単純に実現しようとしたらどちらかになりそう。

  • EntityをSerializableにする
  • MonoBehavior継承したScriptにメンバ変数を持たせて内部でEntityを生成する

前者はありだけど、インスペクタからごにょごにょしたいがためにやるのはなんだか・・という気持ちに。 ならば後者かなと思ったが、Entity生成のためにプリミティブなメンバ変数を用意する必要があるので、ちょっと散らかしてしまうなあという気持ちになってしまう。するとこれはつまりDataStoreの仕事では?となった。

なので、InspectorのDataStoreを作ってみる。

[Serializable]
public class LifeStoreInInspector : IDataStore<Life> {
    public int max;
    public int current;
    public Life ToEntity() {
        // いい感じに生成して返す
    }
}

これをComponentに持たせてインスペクタからいじれるようにすればやりたいことは達成できる。持つ側もEntity用のパラメータをそれぞれ持たせるよりは見通しがよくなったかなーというくらいの気持ち。 でも、SerializableせずにMonobehavior継承したComponentとして独立させた方が切り分け方として正しいのかもしれない。