4-3. メタテーブルを用いたクラス実装
メタテーブルを用いたクラス実装
クラスによるオブジェクト指向プログラミングは、エクスペリエンスに登場するオブジェクト単位でのパラメータ管理や機能実装をしやすくする効率的なプログラミング手法で、ゲーム開発でもよく使われる手法です。
Luaでは言語機能としてクラスの機能はありませんが、メタテーブル機能を使うことで、tableを利用したクラス実装(プロトタイプベースのクラス実装)が可能です。Robloxでは、ModuleScript上でメタテーブル機能を利用して実現します。ここでは、具体例としてCarクラスの例を通じて、メタテーブルの概要とクラス・インスタンス化の実現方法を示します。
Luaのメタテーブル機能について
クラスとそのインスタンス化は、Luaのメタテーブルの特に以下で挙げる機能を利用して実現されます。
- メタテーブルはテーブルへの特殊な振る舞いを定義できるテーブルの拡張データ
- メタテーブルのフィールドにテーブルを指定するとそのテーブルのフィールドも利用可能になる
- テーブルデータには関数で任意のメタテーブルをもたせることができる
にクラスの機能となるメソッドやクラス変数をもつテーブルを指定、それを通常のテーブルデータにメタテーブルとして付与することで、メタテーブル側にクラス機能をもち、通常テーブルでインスタンスごとのプロパティをもつ振る舞いを実現します。すなわちクラス機能をもったインスタンス化ということになります。
メタテーブルはLua言語自体のテーブルの拡張的な振る舞いです。より詳細な情報は以下を参照ください。
Carクラスの定義
以下でメタテーブルを使ったCarクラスと、そのインスタンス化の例を示します。
関数が、Carインスタンスを作成するコンストラクタです。この関数内でを呼び出すことにより、空のテーブルにCarをメタテーブルとして設定したテーブルインスタンスを生成します。Carは2行目の、
によりの関数をメタテーブルが設定されたテーブルから利用可能になっており、メソッド(、)が利用できるようになります。加えて、new関数内で指定するプロパティ(、)は通常のテーブルの値であり、インスタンスごとに固有の値を保持できるようになっています。
Carクラスの使用
上述のCarクラスをインスタンス化して利用する例が以下です。
このスクリプトでは、を使用して新しいCarインスタンスを作成し、そのクラスのメソッドを使用して車の速度を制御しています。クラス共通の機能を利用しながら、インスタンスごとにプロパティが管理されています。
メタテーブルの指定の書き方
上述したクラス定義は、により、Carテーブル自体がメタメソッドの役割も果たすようにする書き方で、少し特殊な書き方にも見えます。メタテーブルの指定は、実際はにCarテーブルが指定されればよいだけなので、以下のようなを省いた書き方も可能です。
ただ、通常は前者となるを用いた書き方が一般的と言えます。細かな点ですが、前者のほうがメタテーブル自体の新規作成は1度で済ませている(後者は都度作成している)という点でわずかに効率が良い点や、コードのみやすさなどの点から好まれます。基本的には、前者の書き方をLuaのクラス定義の基本形としておぼえておくとよいでしょう。
クラス活用の意味
このようにModuleScriptとメタテーブルを組み合わせることで、Luaにおけるクラスのような構造を作成し、オブジェクト指向プログラミングの概念を効果的に取り入れることができます。Carクラスの実装は、ゲーム内で車両の動作をカプセル化し、その操作をより整理された方法で行うことを可能にします。このアプローチは、ゲーム内の様々なエンティティに適用でき、コードの再利用性と整理を助けます。