Unityでデータを扱うということ
注意
勉強中なので、適当(悪い意味)な事をかいてしまうかもしれません。許してください。
前書き
僕はOOPが苦手なので、なんでもかんでもクラス分割をしてしまい、無意味なクラスが増えてどうしようもなくなるということがよくおきます。
クラス分割をすると、モジュール同士の関係が疎結合になり、密結合なプログラムを書くのを防ぎます。
逆に言うと、本来、疎結合にするべきでないモジュールをクラス分割してしまうと、参照を相互に持ったり、コンストラクタに参照を渡さないといけなくなったり、無駄に継承関係が入ったり、散々なことになります。
まず、クラス設計を考える前にデータ設計を考えると良いと私は考えます。
型ベースで考えるのではなく、クラスをInstance化したオブジェクトをどう扱うかを考えます。
Unityでのデータの扱い方
Unityでは、スクリプト(MonoBehaviourの派生)をGUITextや3DモデルといったGameObjectにくっ付けることで、プログラムとの連携をとります。ただし、これはクラスをくっ付けたと考えるのではなく、オブジェクトをくっ付けたと考えるほうがいいでしょう。
それらのObjectはフィールドをinspectorで変更できます。ただし、それはUnityがデフォルトで認識できる種類のフィールドのみです。(基本型、配列、非GenericなSeriarizableオブジェクト等) 勿論そのObjectのクラスに対するinspectorを自分でむりやり定義することもできますが、恐らく値を保存するのはうまくいきません。(OnInspectorGui)
UnityではObjectをPrehabとして分離することができます。(ScriptableObject) C#プログラムにおける参照型のObjectのようなものです。これは、GameObjectとは独立で存在するObjectで、値をいじることもスクリプトから読み込むこともできます。 このObjectを活用できるようにプログラム全体の設計を組むと良いのではないでしょうか。
型について
Unityでは使いやすい型と使いにくい型があるようで、それを意識すると少しはプログラム設計がよくなるのではないでしょうか。
ジェネリック型
データを表すのに本当にジェネリック型が必要ですか?
(でも右と左の事例は辛かった)
デリゲート型
デリゲート型はinspectorで見えないし、インターフェース使っても誰も文句言わないよ。
インターフェース
鬼門。インターフェースではそのインターフェース型とObject型であることは保証できるけど、UnityEngine.Object型であることは保証できない。諦めて、抽象クラスを使おう。 そのときに、多重継承問題がでてきたら、泣こう。
コレクション
inspectorに表示されない(?)。そのコレクションには多くのデータが入るのですか?挿入や削除といったクエリが頻繁に起こるのですか?そうでないなら、配列を使いましょう。
あとがき
と、思って今コードを書いているところです。 乱文すみません。