i-school - 3Dスライダーゲーム 発展8
 以下の内容で順番に実装を進めていきます。

発展8 ー平面をタップした地点にステージを生成する機能の実装ー

12.平面をタップした地点にステージを生成する機能の実装



 新しい学習内容は、以下の通りです。

 ・enum の列挙子と機能



12.平面をタップした地点にステージを生成する機能の実装

1.設計


 前回の手順では、平面感知の機能が動作するかを検証する意味合いを含めて、ヒエラルキーにある Stage ゲームオブジェクトを非表示 → 再表示させていました。

 この手順では AR Camera によって平面感知したあとの処理を修正し、平面をタップした地点にステージを生成する処理に変更します。
そのためには、ヒエラルキーにある Stage ゲームオブジェクトを事前にプレハブ化しておいて、
そのプレハブをタップした地点に生成するようにします。
よって前回の手順とは異なり、非表示の Stage ゲームオブジェクトを表示する、という動作ではなくなります。

 また、AR の状態を管理できるようにステート機能を実装します。
ステートは enum で実装します。enum に慣れてきたら、ステートのデザインパターンでの実装を検討してみましょう。


2.ARGameManager スクリプトを修正する


 事前に用意しておいたステージを表示する機能修正し、タップした地点にステージのゲームオブジェクトを生成する処理に変更します。


ARGameManager.cs

<= クリックすると開きます。



3.<enum の列挙子と機能>


 enum(イニューム)とは C# に用意されている構造体に分類される機能の1つです。列挙(れっきょ)型と呼ばれます。

 bool 型を利用すると if 文において2つの分岐パターンを作成することができます。
ですが bool 型には true/false の2つの状態しか値として持たないため、3つ以上の状態を管理することが出来ません。

 このような、2つ以上の情報を1つの情報源として管理する場合には、enumでその種類を登録しておくことをおすすめします

 enum で作成する型には任意の名前を付けることが出来ます。クラスと同じです。
宣言した enum 内には任意の名前の列挙子を作成できます。数に指定はなく、日本語でも作成できます。

<今回実装した enum で作成された ARState 型の宣言>
    public enum ARState {
        None,         // Editor でのデバッグ用。この部分が列挙子。
        Tracking,     // 平面感知中
        Preparate,    // ゲーム準備前。感知終了後、Ready の前の状態
        Ready,        // ゲーム準備OK
        Play,         // ゲーム中
        GameUp,       // ゲーム終了
    }

 今回は、AR の状態を表現する方法として enum によって作成された ARState 型を用意しました。
また、None 〜 GameUp まで、6種類の列挙子を宣言しています。これは自由に名前の変更、新しい列挙子の追加・削除ができます。



 作成した ARState 型は情報源、つまり、設定であり、この情報を実際にゲーム内で利用するためには、ARState 型の変数の宣言を行います。


<ARState 型の変数の宣言>
 public ARState currentARState;

 以上のように enum は、enum を宣言して設定を行う部分と、それを利用するための変数の宣言の2つが必要になります。
自作した enum の ARState 型には、ARState 型内に宣言した列挙子の値を1つだけ代入することが出来ます

<列挙子の代入>
  // ステート管理処理を追加
  currentARState = ARState.None;

 代入する場合には必ず、[enum の型名.列挙子名] で指定をします。列挙子名のみでの指定は出来ません。

 このように1つの変数内には、いずれかの列挙子の値が1つだけ代入できるため、
bool 型とは異なり、宣言した列挙子分の分岐を用意することが可能になります
よって、true なら/false なら、という形ではなく、現在の ARState の値が None なら / Tracking なら / GameUp なら、という風に列挙子の値に合わせて分岐が作成できます。



 enum を利用する場合、その登録してある列挙子からしか情報を指定できませんので、
例えば、文字列と異なり、指定に際して打ち間違えが発生しませんので、不備の値が入ることも防ぐことが出来ます

 以上のことから、ゲームの内容に応じた enum を考えて作成して運用します
ほかには、プレイヤーの状態用(毒、混乱、痺れとか)、アイテムの種類(消耗品、武器、防具、など)、
ゲームの状態管理(ゲーム開始前、ゲーム中、ゲーム終了)など、非常に応用が利く機能です。



 なお enum では各列挙子に自動的に整数の番号が与えられます一番上から 0 で連番になっています
今回の場合であれば、None には 0、GameUp には 5 の数字が与えられています。

 この番号は見えない情報ですが、列挙子を int 型にキャストを行うことで取得して利用出来ます
下記の例の場合、enumValue には 1 が代入されます。

<enum の列挙子のキャスト>
 int  eventValue = (int)ARState.Tracking;

 また、列挙子の宣言時に数字を指定して代入することも可能です。その場合には連番ではなく、指定した数値を取得出来ます。

<数字の代入の例(今回この方式は利用しません)>
public enum ARState {
        None = 10,         // Editor でのデバッグ用
        Tracking = 3,      // 平面感知中
        Preparate = 50,    // ゲーム準備前。感知終了後、Ready の前の状態
        Ready = 100,       // ゲーム準備OK
        Play = 1,          // ゲーム中
        GameUp = 0,        // ゲーム終了
    }
}

 上記のように代入されている場合には、列挙子を int 型にキャストすると、代入してある値が取得出来ます
今回は数字の代入は行っていませんので一番上の列挙子には 0 から順番に採番されています。

 enum は自分の目的に合わせて自由に作成できます。
今後も必要に応じて作成し、プログラムを読みやすく、管理をしやすいゲーム環境を作っていくようにしましょう。


4.AR Session Origin ゲームオブジェクトの設定を確認する


 AR Session Origin ゲームオブジェクトを選択してインスペクターを確認します。

 最初に ARGameManager スクリプトに新しい CurrentARState 変数の情報が1つ追加表示されていますので確認しておきます。

 enum の変数がインスペクター上に表示されると、プルダウンメニュー内に列挙子が表示されます。

 この CurrentARState 変数はゲームを実行するたびに、プラットフォームに応じたステートが設定されますので、
いまは None のままで問題ありません。一応、プルダウンメニューを操作して、インスペクターより変更が行えることだけ確認しておいてください。



 次に、StageObj 変数の情報を変更します。ここには現在、ヒエラルキーにある Stage ゲームオブジェクトの情報がアサインされていますが、
代わりに、Prefabs フォルダにある Stage ゲームオブジェクトのプレファブをドラッグアンドドロップしてアサインします

 これは、事前に用意してあるステージではなく、プレファブになっているステージをタップに合わせて生成して利用するためです。
アサインを間違えていると生成処理が上手くいきませんので、手順を間違えないようにしてください。


インスペクター画像



 以上で完成です。


5.ゲームを実行して動作を確認する


 ビルドを行い、実機にてテストを行います。

 カメラを床やテーブルなどに向けて動かしてみてください。
平面感知に成功すると、その地点に AR Default Plane ゲームオブジェクトが生成されて、範囲が自動的に調整されます。

 平面感知している部分をタップすることで、ステージが表示されれば制御成功です。


6.問題点の確認


 この時点で、2つほど、問題点があります。

 1つは、平面感知をしている処理を続いているため、平面感知用のゲームオブジェクトがずっと見えてしまっていること。
もう1つは、ARCamera がプレイヤーを追従しないため、カメラが動かないことです。

 この2つの現象を確認した上で、次の手順で順番にこれらの問題点を解消していきます。



 以上でこの手順は終了です。

 => 次は 発展9 −平面感知用ゲームオブジェクトを非表示にする機能の実装− です。