i-school - 3D宝石集めアクションゲーム 手順15
 前回の手順に続けて UI の学習を行います。
この手順では、前回作成した Canvas を利用して、ゲーム画面のスコア表示を更新する機能の追加していきます。


<実行動画>
動画ファイルへのリンク



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

手順15 ーゲーム画面のスコア表示を更新する機能の追加ー
1.ゲーム画面に現在の得点をスコアとして更新表示する



<新しく学習する内容>
 ・インスペクターのアサイン情報の読み方
 ・スクリプト内で別のスクリプトの処理を実行していく方法(復習)



1.ゲーム画面に現在の得点をスコアとして更新表示する

1.設計


 Canvas ゲームオブジェクト内にスコア表示用のゲームオブジェクトを設置しましたので、次は、このスコアの表示を更新していく処理を実装していきます。

 スコアの点数表示は txtScore ゲームオブジェクトにアタッチされているText コンポーネントによって制御されています。
この Text コンポーネントに対しての紐づけを行い、命令を出すことでスコアの表示制御を行います。

 今回の設計では、UI関連の処理を担当する新しいスクリプトである UIManager を用意して、得点の表示を更新する UpdateDisplayScore メソッドを用意します。
このメソッド中で、Textコンポーネントへの処理を実行して、得点の表示を更新するようにします。
一連の処理を1つのメソッド単位で用意しておくことで、外部のスクリプトからも、この処理を行いたい場合には、メソッドを呼び出すことで実行することが出来ます。

 得点を獲得する処理は ScoreManager スクリプトに AddScore メソッドとして実装してありますので、
この部分にさらに処理を追加し、サークルを通過して得点を獲得したら、UIManager スクリプトの UpdateDisplayScore メソッドに対して実行命令を出します

 UIManager スクリプトの UpdateDisplayScore メソッドでは、txtScore ゲームオブジェクトの持つ Text コンポーネントの Text プロパティに命令を出して値を書き換えます。

 この挙動がゲーム画面に表示されるようになるため、ゲーム上は、サークルを通過するたびにスコアを更新していくように見えます。


<スコア表示までの処理の流れ>

1.UIManager スクリプトを作成し、スクリプトを通じて、txtScore ゲームオブジェクトの Text コンポーネントを操作できる状態にする
2.UIManager スクリプト内に UpdateDisplayScore メソッドを public 修飾子で用意し、この処理において Text コンポーネントの Text プロパティの得点を更新する。
  そのため、このメソッドでは int 型の引数を用意し、その値を受け取り Text プロパティに代入できるようにする

3.ScoreManager スクリプトの AddScore メソッドを修正し、UIManager スクリプトの UpdateDisplayScore メソッドに対して実行命令を出す。
  このとき、totalPoint 変数を引数として渡すことで、UpdateDisplayScore メソッドで totalPoint 変数の値を利用できる状態にする

 以上のように、新しいスクリプトの作成と、ScoreManager スクリプトの修正を行った結果

4.UIManager スクリプトの UpdateDisplayScore メソッドが実行されて、引数として受け取った totalPoint 変数の値を
    txtScore ゲームオブジェクトにアタッチされている Text コンポーネントのプロパティに代入して更新する命令を行う

 このような処理の流れ・ロジックになります。
処理は順序だてて、順番に1つずつ追加していくことを考えましょう。

 それではまず最初に、ScoreManager スクリプトがメソッドを実行するためは、実行用のメソッドを定義しておく必要がありますので
UIManager スクリプトを作成し、その中にメソッドを定義します。

 自分で処理を考えて組み立てていく際には、教材の手順を参考にしてください。
処理の全体像を作ってから、処理の最後の部分(ゴール地点)から作成を始めると作りやすいです。


2.UIManager スクリプトを作成する


 UI関連の処理をまとめて管理するためのマネージャークラスを作成し、今回もその中に処理を記述するようにします。

 Scripts フォルダ内で右クリックをしてメニューを表示し、 Create => C# Script を選択し、名前を UIManager に変更します。
ダブルクリックして編集しましょう。

 もしも処理のイメージとしてロジックが浮かんでいるのであれば、上記の設計を参考に、まずは自分で処理を書いてみましょう。


UIManager.cs

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


 スクリプトを作成したらセーブしてください。


3.UIManager ゲームオブジェクトを作成し、UIManager スクリプトをアタッチして設定を行う


 ヒエラルキーの空いている場所で右クリックをしてメニューを開き、Create Empty を選択します。
新しい空のゲームオブジェクトが作成されますので、名前を UIManager に変更します。


ヒエラルキー画像




 作成した UIManager スクリプトをドラッグアンドドロップして UIManager ゲームオブジェクトにアタッチしてください。
アタッチ後は必ず、ゲームオブジェクトを確認して、スクリプトがアタッチされているかを確認してください。


UIManager ゲームオブジェクト インスペクター画像




 SerializeField属性で宣言している変数が表示されていますので、このスクリプトから操作を行いたいゲームオブジェクトをこちらにドラッグアンドドロップしてアサインします。
どのゲームオブジェクトにアタッチされているコンポーネントを操作したいのか考えて、ドラッグアンドドロップして情報を登録してください。


UIManager ゲームオブジェクト アサイン後のインスペクター画像



 ゲームオブジェクトをドラッグアンドドロップしてアサインすると、自動的にそのゲームオブジェクトにアタッチされている対象のコンポーネントを登録します。


4.<インスペクターのアサイン情報の読み方>


 インスペクターのアサイン情報ですが、アサイン前は None (アサイン可能な型名)  が表示されています。(型) は、この変数の型です。
例えば今回の txtScore 変数は Text 型の変数ですので、None(Text) と表示されています。Noneとは、アサインが行われていない状態を表しています


アサイン前の情報



 アサイン後は、ゲームオブジェクト名(そのゲームオブジェクトの持つコンポーネント/スクリプト名) という書式で表示されています。


アサイン後の情報



 今後もアサインは頻繁に操作します。読み方をしっかりと覚えておいてください。


 以上で UIManager 関連の設定は完了です。


5.ScoreManager スクリプトを修正して、UIManager スクリプトの UpdateDisplayScoreメソッドを呼び出す命令を追加する


 設計した内容をスクリプトに反映していきます。こちらもロジックが浮かんでいるようであれば、処理を見ずに書いてみましょう。
 
 まずは宣言フィールドに UIManager スクリプトの情報を代入するための変数を SerializeField属性で宣言しましょう。
事前にインスペクターから UIManager スクリプトの情報をアサインして登録できるようになります。

 次に、AddScore メソッド内に、UIManager スクリプトに用意してあるスコアの表示を更新する UpdateDisplayScore メソッドを呼び出します。
このとき、処理を書く順番に注意しましょう。

 UpdateDisplayScore メソッドには引数として totalPoint 変数を渡すのですから、
得点の加算処理が終わり、最新の状態の totalPoint 変数を渡せる状態になってから呼び出すようにしてください。
そうしないと加算前の値を渡すようになってしまい、想定している挙動にならないためです。


ScoreManager.cs

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


 スクリプトを修正したらセーブを行います。



 ScoreManager スクリプトがアタッチされているプレイヤーのゲームオブジェクトのインスペクターを確認します。
新しく SerializeField属性で宣言した uiManager 変数が表示されていれば問題ありません。


プレイヤーのゲームオブジェクト インスペクター画像



6.<スクリプト内で別のスクリプトの処理を実行していく方法>


 以前の手順でも説明しましたが、スクリプトは、外部のスクリプトの情報を取得することで
外部スクリプトへの参照や、外部のスクリプトに定義されているメソッドを実行することが出来るようになります。

 外部のスクリプトの情報を取得(変数に代入したり)した場合、そのスクリプトの扱っている public 修飾子の情報が扱えるので、
public 修飾子の変数の情報を参照して利用したり、public 修飾子のメソッドを呼び出すことが可能になります


 [SerializeField]
  private UIManager uiManager;     // UIManager スクリプトを利用するために UIManager スクリプトの情報を代入する変数


 public void AddScore(int amount) {

    totalPoint += amount;
        Debug.Log("スコア合計値 : " + totalPoint);

        gemCount++;
        Debug.Log("宝石の獲得数 : " + gemCount + " 個");

        uiManager.UpdateDisplayScore(totalPoint);  // <= この処理です
  }

 public なメンバ変数として UIManager スクリプトの情報を uiManager 変数に代入して参照できる状態にしています。これはインスペクターで設定しておきます。
このとき、UIManagear スクリプト内にある public 修飾子で宣言している変数やメソッドも、ScoreManager スクリプト内で扱えるようになります。

 これを利用し、AddScore メソッド内では、UIManager スクリプトに対して命令を出し、
UIManager スクリプト内にある public 修飾子で宣言されている UpdateDisplayScoreメソッドを実行することが出来ます。

 今回のように、変数内に取得したスクリプトがどのような情報を扱えるのかを把握して設計しておくことで、
スクリプトを通じて、命令を実行していくことが可能です。設計が重要といわれる所以です。


7.プレイヤーのゲームオブジェクトにアタッチされている ScoreManager スクリプトの設定を行う


 新しく追加されたアサイン情報を登録しましょう。
先ほどのインスペクターの読み方を参考にして、どの情報が必要かを考えてアサインしてください。


プレイヤーのゲームオブジェクト インスペクター画像


 以上で設定は完了です。


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


 事前の準備を行います。

 Canvas 内にある txtScore ゲームオブジェクトを選択し、インスペクターを確認します。
Text コンポーネント内の Text プロパティの値を 0 に設定します。

 Game ビューのスコア表示が 0 になっていることを確認してください。


インスペクター画像



Game ビュー画像




 ゲームを実行して、プレイヤーを宝石に侵入させて得点を加算してください。
画面のスコア表示がそれに合わせて totalPoint 変数の値に更新されれば制御成功です。
Console ビューに totalPoint 変数の値が表示されますので画面のスコア表示と照合しましょう。

 更新されない場合には、アサイン情報が間違っていないか、他にエラーが表示されていないかを確認して原因を特定します。


<実行動画>
動画ファイルへのリンク



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

 => 次は 手順16 ー宝石の自動生成機能の追加ー です。