i-school - 3Dスライダーゲーム 発展6
 AR 用にログを表示する機能を実装します。

 以下の内容で順番に実装を進めていきます。

発展6 ーログ表示機能の実装ー

10.デバッグを効率化するためのログの表示機能を追加する



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

 ・シングルトン・デザインパターンによるクラスの運用方法



10.デバッグを効率化するためのログの表示機能を追加する

1.設計

 
 AR は実機でテストを行う必要がありますが、エディターと異なり、Console ビューがないので、
Debug.Log メソッドを利用しても、実機には表示することが出来ません。

 このままでは不便なので、Console ビューの代わりに Canvas ゲームオブジェクトと Text ゲームオブジェクトを利用して、
ゲーム画面内に疑似的な Console ビューを作成し、ここに Debug.Log メソッドの内容を表示する機能を作成します。

 AR、VR などの実機でのテストが不可欠な場合には、こういったログ表示機能を事前に作成しておくことで、実機テストの際にデバッグの効率が上がります


2.Canvas_Debug ゲームオブジェクトを作成する


 ヒエラルキーの空いている場所で右クリックをしてメニューを開き、UI => Canvas を選択します。
Canvas と EventSystem が作成されますので、Canvas の名前を Canvas_Debug に変更しておきます。


ヒエラルキー画像




 Canvas を作成したら、CanvasScaler コンポーネントを確認し、Game ビューの解像度と同じ設定にしてください。

 UI Scale Mode を Scale With Screen Size に変更すると、Reference Resolution の項目が追加されますので、
こちらの Width と Height の値を Game ビューの設定に合わせてください。

 Scale Match Mode は Expand に変更してください。


インスペクター画像(参考)



3.Canvas_Debug ゲームオブジェクトの子オブジェクトとして、txtDebug ゲームオブジェクトを作成する


 Canvas_Debug ゲームオブジェクトの上で右クリックをしてメニューを開き、UI => Text を選択します。
名前を txtDebug に変更します。txtLog などでもいいでしょう。


ヒエラルキー画像




 こちらのゲームオブジェクトのサイズがゲーム画面に表示するログ表示部分になります。
なるべく邪魔にならない位置に、ある程度の大きさで作成しておいてください。

 文字サイズ、フォント、 Outline などの文字装飾は自由に設定してください。


インスペクター画像(参考)



Sceneビュー画像




4.LogDebugger スクリプトを作成する


 ログ表示を行うためのスクリプトを作成します。
シングルトンクラスとして作成しておくことで、いずれのクラスからでも自由にアクセスが行える状態にしておきます。

 外部のクラスから DisplayLog メソッドを実行してもらい、引数で文字列の情報を受け取れるようにしてあります。
それを txtDebug ゲームオブジェクトの Text コンポーネントを通じてログ表示を行います。


LogDebugger.cs

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


 スクリプトを作成したらセーブします。


5.<シングルトン・デザインパターンによるクラスの運用方法>


 シングルトンとは、数多くあるデザインパターンの1つです。
そのクラスのインスタンスが必ず1つであることを保証するデザインパターンのことを言います。

 LogDebugger クラスでは、このシングルトンを採用しています。
つまり、ゲーム中を通じて、この LogDebugger クラスが1つしか存在できないようになります。
実装例は複数ありますが、一番読みやすい方式で記述しています。



<シングルトンデザインパターンのクラスの作成方法>
    public static LogDebugger instance;  // クラス名と同名の型を static で宣言する

    private void Awake() {
        if (instance == null) {
            instance = this;
            DontDestroyOnLoad(gameObject);
        } else {
            Destroy(gameObject);
        }
    }



 ポイントは、自分自身の LogDebugger 型を static 修飾子付きの instance 変数として宣言していることです。
この instance 変数が LogDebugger クラス自身が代入された情報として利用することになります。

 Awake メソッドを利用して、instance 変数が null (空っぽ) である場合には、LogDebugger クラス(this)を代入します。
次の DontDestroyOnLoad メソッドは Unity が用意しているメソッドで、引数に指定されたゲームオブジェクトはシーン遷移をしても破壊されてないゲームオブジェクトになります。
この DontDestroyOnLoad メソッドはシングルトンデザインパターンにする際に一緒に用いられることが多いです。

 そして instance 変数が null ではない場合、つまり、2つ目以降の複数の LogDebugger クラスが存在する場合には、その LogDebugger クラスのゲームオブジェクトを Destroy します。
この手順により、LogDebugger クラスがアタッチされているゲームオブジェクトが常にヒエラルキー上に1つしか存在しない状態を作り出しています

 このシングルトンによってインスタンスが1つか生成されないことが保証されますので、
逆説的に考えると、この LogDebugger クラスへの参照は、いずれのクラスからであっても変数を介さずに参照を行えるようになります。



 例えば、NonPlayerCharacter というクラスがあり、その NonPlayerCharacter クラスを持つゲームオブジェクトが5つあった場合、
どの」NonPlayerCharacter クラスであるかを確定できないと、対象となる NonPlayerCharacter クラスへは参照できません。
そのため、NonPlayerCharacter 型の変数を用意して、その変数へ参照したい NonPlayerCharacter クラスを代入することによって、
はじめて NonPlayerCharacter クラスの情報を扱うことができるようになります。これが情報を扱う際の基本的な処理になります。

 ですがシングルトンである LogDebugger クラスの場合には、このインスタンスは常に1つしかないことが保証されていますので、
どの」という指定の部分が不要になります。よってクラスの特定ができているため、変数への代入が不要になります。
LogDebugger という指定はすなわち、自動的にただ1つの LogDebugger クラスの参照が行われることになるためです。

 この機能を利用して LogDebugger クラスを作成しておくことで、どのクラスからでも参照しやすい設計にしておきます。


6.Canvas_Debug ゲームオブジェクトに LogDebugger スクリプトをアタッチして設定を行う


 Canvas_Debug ゲームオブジェクトに LogDebugger スクリプトをドラッグアンドドロップしてアタッチします。

 インスペクターを確認し、txtDebug 変数に同名のゲームオブジェクトをドラッグアンドドロップしてアサインします。
自動的に Text コンポーネントの情報が登録されます。


インスペクター画像



 以上でログ機能は完成です。
あとは、任意のクラスから DisplayLog メソッドを実行することで、ゲーム画面にログ表示が実行されます。



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

 => 次は 発展7 −AR Camera による平面の感知機能の実装− です。