Unityに関連する記事です

 ここからはUI(ユーザーインターフェース)について学習しながら実装を行います。
この手順ではゲーム画面に獲得した得点をスコア表示し、スコアが更新されるたびに画面のスコア表示も更新する処理を実装します。


<完成画像>



<実装動画>
https://gyazo.com/bc369da92e00d17bfb879bab324b8a25


手順19 −スコアの表示制御−
33.Canvas内にUI部品を作成する(スコア表示)
34.画面に現在の得点をスコアとして更新表示する



新しく学習する内容


 ・アンカー設定
 ・インスペクターのアサイン情報の読み方
 ・スクリプト内で別のスクリプトの処理を実行していく方法



33.Canvas内にUI部品を作成する(スコア表示)

1.設計


 ゲーム画面のUI(ユーザーインターフェース)については別の記事に詳しくまとめてありますので、そちらをご確認ください。

 => 画面UI

 この手順からは順番に、ゲーム内に実装されている内部処理をゲーム画面上に表示・更新する処理を実装していきます。

 前回の手順で PlayerController スクリプトには score 変数が追加されました。
こちらの情報をゲーム画面に表示して、サークルをくぐるたびに得点がアップしていく表示を実装します

 必要な情報としては score 変数ですが、こちらをゲーム画面に反映するためのゲームオブジェクトも必要になります

 この時に利用するのが、UIです。Canvas というコンポーネントを持つゲームオブジェクトの中に(子オブジェクトとして)
ゲームオブジェクトを設置することで、ゲーム画面の一定の位置に常に情報を表示する機能を実装出来ます

 今回はゲーム画面の左上に常時スコアの数字の表示を行い、サークルをくぐって得点を獲得したときに、スコアの数字を更新するようにします。
なお、表示する位置に関しては任意の位置に変更していただいて構いません。
自分がもしもユーザーだったら、どの位置に、どの位の大きさであれば見やすいか、そういったことを考えて配置を行います。


 最初に Canvas ゲームオブジェクトの作成と、スコアの表示を行うためのゲームオブジェクトの作成を行います。
それから、PlayerController スクリプトを修正して、score 変数の情報を、スコア表示用のゲームオブジェクトに対して送り出す制御を実装します。


ヒエラルキー画像 完成図



Gameビュー画像 完成図



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


 ヒエラルキーの空いている場所で右クリックをしてメニューを開き、UI => Canvas を選択します
ヒエラルキーに Canvas ゲームオブジェクトが作成されます。
一緒に EventSystem ゲームオブジェクトも追加されます。これは1セットで扱いますのでそのままで問題ありません。


ヒエラルキー画像



 Canvas ゲームオブジェクトをダブルクリックしてください。
いままで作業を行っていた Scene ビューの上の方に Canvas 用の場所が追加されています。
これはゲーム画面に Canvas が表示されてしまうと、双方の編集作業が大変になるための措置です。

 Canvas では設定した情報は、ゲーム画面に一緒に表示されるようになります
そのため、作業のスペースを分けているだけであって、同じゲームの画面として表示されますので問題ありません


<検証動画 作業スペースとして分けているだけ>
https://gyazo.com/f44e8e251d24e3b2c08d4925a686e64b



 Canvas ゲームオブジェクトのインスペクターを確認し、Canvas Scaler の UIScaleMode の設定を Scale With Screen Size に変更します。
変更すると Reference Resolusion という設定が追加されますので、こちらに、Game ビューで使用している解像度と同じ大きさを指定します。
今回の教材では 2880 * 1440 の解像度で設定していますので、こちらも同じ数字に指定します。これは、ご自分の設定した解像度と同じにしてください。

 また Screen Match ModeExpand に変更しておきます。
この設定にしておくことで Canvas の設定を水平・垂直に拡大してくれますので、スマホの解像度とCanvasのサイズに合わせてくれます。



 なお、今回のように Canvas の Render Mode を初期設定である Screen Space - Overlay に設定している場合、
その Canvas は「Camera を用いず(カメラの有無に関係なく)、常に Game 画面の最前部に Canvas 内の UI を表示する」という設定になります。

 よって、Canvas には位置の概念がなくなるため、 RectTransform の各値はいじれません。気にせずに作業してください。


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



Gameビューの解像度(この解像度とCanvasの解像度を合わせる)



Sceneビュー画像



 以上でこのゲームオブジェクトの設定は完了です。


参考サイト
Metal Brage 様
画面解像度とスケーリング
http://www.metalbrage.com/UnityTutorials/uGUI/Scal...


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


 Canvas ゲームオブジェクトの上で右クリックをしてメニューを開き、Create Empty を選択します。
新しく空のゲームオブジェクトが作成されますので、名前を Scores に変更します。
Scores ゲームオブジェクトは、スコア表示に関連するゲームオブジェクト群をまとめておくための、フォルダ役のゲームオブジェクトです。


Scores ゲームオブジェクト ヒエラルキー画像



 Scores ゲームオブジェクトを選択して、RectTransform コンポーネントがアタッチされているか確認します。
Canvas ゲームオブジェクトに含まれるオブジェクトは Transform コンポーネントではなく、RectTransform コンポーネントによって位置情報を管理しています
もしも通常の Transform コンポーネントがアタッチされている場合には、再度作り直してください。


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



Scores ゲームオブジェクト Sceneビュー画像(Sceneビューの中央にある)




 Scores ゲームオブジェクトの位置とアンカーを変更します。
RectTransform コンポーネント内にある Anchor(アンカー)をクリックして、Alt キーを押しながら、Top Left の位置をクリックしてください
Scores ゲームオブジェクトが画面の左上の位置に移動するとともに、アンカーの位置も画面左上に設定されます。


<手順動画 アンカーの設定(Altキーを押しながらクリックすることで、アンカーの設定とゲームオブジェクトの移動が一緒に行われる)>
https://gyazo.com/72638c932c398f8ca482dbe0fef4fb89


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



Sceneビュー画像



 以上で設定は完了です。


4.<アンカー設定>


 Canvas用のゲームオブジェクトの位置情報は RectTransform コンポーネントによって管理されています。
RectTransform コンポーネントを持つゲームオブジェクトは、ワールド座標による座標の計算ではなく、
親となるゲームオブジェクトからみてどの位置にいるかというローカル座標(相対座標)による座標の計算を行っています

 この RectTransform コンポーネントには通常の Transform コンポーネントにはない情報がいくつかあります。
その1つがアンカーです。


アンカーのアイコン

 

 アンカーとは、親のゲームオブジェクトからみて、このゲームオブジェクトの基準地点をどの位置に設定するか、という情報です。
ローカル座標によって座標を計算していますので、親のゲームオブジェクトからみて、どこから計算を始めるかというのは重要な設定情報です。
基本的には Center Middle という設定になっており、親のゲームオブジェクトからみて中心の位置をアンカーに設定しています。


アンカーの設定

 

 今回、Scores ゲームオブジェクトに設定したアンカーは、Top Left の位置です。(これはプリセット情報なので、もっと詳細に自分でも設定できます。)
親オブジェクトである Canvas ゲームオブジェクトからみて、画面の中心を基準値としてではなく、画面の左上を基準として座標の計算を行うようにしています。
 
 理由としては、ゲーム画面の比率が変化した際に、RectTransform コンポーネントを持つゲームオブジェクトは、アンカーの位置を基準に配置されるため
画面の比率が変化しても、その状態に対応して、自分の位置を設定してくれるようになるためです

 例えば今回のように左上にアンカーを設定しておくと、どのゲーム画面でゲームを実行しても、常に画面の左上からみて座標の計算をして、ゲームオブジェクトを配置してくれます
そうすることによって、ゲーム画面を変えたらスコア表示が見えなくなってしまった、という事態を回避出来るようにしています。


参考サイト
Unity公式ユーザーマニュアル
基本的なレイアウト
https://docs.unity3d.com/ja/current/Manual/UIBasic...
徒然エンジニアブログ様
【Unity】UIの基本(Canvas,描画順,アンカー,ピボット)を徹底解説してみる
https://turedureengineer.hatenablog.com/entry/2019...


5.Scores ゲームオブジェクトの子オブジェクトとして、imgBackground ゲームオブジェクトを作成する


 Scores ゲームオブジェクトの上で右クリックをしてメニューを開き、UI => Image を選択します。
Imgae コンポーネントがアタッチされたゲームオブジェクトが新しく作成されますので、名前を imgBackground に変更します。


imgBackground ゲームオブジェクト ヒエラルキー画像



 imgBackground ゲームオブジェクトは、スコアの数字表示の背景画像表示の役割を持ちます。


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



imgBackground ゲームオブジェクト Sceneビュー画像




 最初に画像を設定します。
imgBackground ゲームオブジェクトのインスペクターを確認し、Image コンポーネントの Source Image の部分に画像を設定します。

 背景用の画像ですが、インポートしたアセットから選択してもよいですし、画像をダウンロードしてきてインポートして利用しても、どちらでも構いません。
こちらの画像がゲーム画面に適用されます。

 今回はこちらのパスにある画像を利用しています。
Assets/JKT_Art/UI/ICON/map.png

フォルダ画像



インスペクター画像



 画像の設定が終了したら、Raycast Target のスイッチを外してオフにしておいてください。このスイッチの意味は自分で調べてみましょう。



 画像を設定したら、大きさを調整します。この画像内にスコア表示が入りますので、もしも収まりが悪いようでしたら、後で大きさを調整しましょう。
Sceneビューで直接変更してもよいですし、RectTransform コンポーネントの Width、Height の値を変更しても調整できます。
下記のインスペクター画像を参考にして、適宜なサイズに調整してください。(同じである必要はありません)


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



imgBackground ゲームオブジェクト Sceneビュー画像



 以上で設定は完了です。つづいて、この imgBackground ゲームオブジェクトに子オブジェクトを2つ追加していきます。


6.imgBackground ゲームオブジェクトの子オブジェクトとして、lblScore ゲームオブジェクトを作成する


 imgBackground ゲームオブジェクトの上で右クリックをしてメニューを開き、UI => Text を選択します。
Textコンポーネントがアタッチされたゲームオブジェクトが作成されますので、名前を lblScore に変更します。

 lblScore ゲームオブジェクトは、画面上に pts という文字列を常に表示する、ラベルの役割を持ちます。
このゲームオブジェクトではスコアの更新は行いません


lblScore ゲームオブジェクト ヒエラルキー画像



 lblScore ゲームオブジェクトを選択し、Textコンポーネント の Text プロパティ欄に、"pts" と入力してください。
ラベル役のゲームオブジェクトですので、この文字列を常に画面に表示します。フォントの種類やサイズは適宜に調整してください。
位置は中央・中央寄せに設定しています。

 また、Raycast Target のチェックを外してオフの状態にしておいてください。


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



 続いて、RectTransform コンポーネントを確認します。
Sceneビューと RectTransform の Position の値を調整して、適宜な位置に設置してください。
Gameビューで実際にどのように画面に映るか確認することも必要です。


lblScore ゲームオブジェクト Sceneビュー画像



lblScore ゲームオブジェクト Gameビュー画像



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



 以上でこのゲームオブジェクトの設定は完了です。


7.imgBackground ゲームオブジェクトの子オブジェクトとして、txtScore ゲームオブジェクトを作成する


 imgBackground ゲームオブジェクトの上で右クリックをしてメニューを開き、UI => Text を選択します。
Textコンポーネントがアタッチされたゲームオブジェクトが作成されますので、名前を txtScore に変更します。

 txtScore ゲームオブジェクトは、画面上にスコアの値を表示する役割を持ちます。
このゲームオブジェクトの Text コンポーネントの機能を利用して、画面上に獲得しているポイント数をスコアとして表示・更新していきます


txtScore ゲームオブジェクト ヒエラルキー画像



 txtScore ゲームオブジェクトを選択し、Textコンポーネント の Text プロパティ欄に 0 と入力してください
ここにはゲーム中にスクリプトを利用して、動的にスコアの値が表示されます。数字は4〜5桁位まで入ることを想定しておきましょう。

 フォントのサイズは点数が目立つように、lblScore ゲームオブジェクトの Text コンポーネントと同じか、少し大きめがいいでしょう。
フォントも同様に、lblScore と同じフォントを選択してください。文字の位置は中央・右寄せに設定しています
こちらもRaycastTarget のチェックも外してください


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



 続いて、RectTransform コンポーネントを確認します。
Sceneビューと RectTransform の Position の値を調整して、適宜な位置に設置してください。
Gameビューで実際にどのように画面に映るか確認することも必要です。下記の画像も参考してください。
lblScore ゲームオブジェクトと高さの位置を合わせるようにしましょう


txtScore ゲームオブジェクト Sceneビュー画像



txtScore ゲームオブジェクト Gameビュー画像



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



 以上の手順でスコア表示用のゲームオブジェクト群は完成です。



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

1.設計


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

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

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

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

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

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


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

1.UIManager スクリプトを作成し、スクリプトを通じて、txtScore ゲームオブジェクトの Text コンポーネントを操作できる状態にする
2.UIManager スクリプト内に UpdateDisplayScore メソッドを public 修飾子で用意し、この処理において Text コンポーネントの Text プロパティの得点を更新する。
  そのため、このメソッドでは int 型の引数を用意し、その値を Text プロパティに代入できるようにする
3.PlayerController スクリプトの AddScore メソッドを修正し、UIManager スクリプトの UpdateDisplayScore メソッドに対して実行命令を出す。
  このとき、score 変数を引数として渡すことで、UpdateDisplayScore メソッドで score 変数の値を利用できる状態にする
4.UIManager スクリプトの UpdateDisplayScore メソッドが実行されて、引数として受け取った score 変数の値を txtScore ゲームオブジェクトにアタッチされている Text コンポーネントのプロパティに代入して更新する命令を行う

 この手順でロジックを実装します。処理は順序だてて、順番に1つずつ追加していくことを考えましょう。


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.PlayerController スクリプトを修正して、UIManager スクリプトの UpdateDisplayScoreメソッドを呼び出す命令を追加する


 設計した内容をスクリプトに反映していきます。こちらもロジックが浮かんでいるようであれば、処理を見ずに書いてみましょう。
 

PlayerController.cs

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



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


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



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


 前回の手順でも説明しましたが、スクリプトでは、外部のスクリプトの情報を取得し、変数に代入することで、そのスクリプトへの参照や、メソッドを実行することが出来るようになります。

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


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


 public void AddScore(int amount) {

      // スコア加算
      score += amount;

      Debug.Log("現在の得点 : " + score); 

   // UIManager の情報が代入されている変数を利用して UIManager スクリプトの UpdateDisplayScore メソッドを呼び出す処理を実行する
    // 引数として score 変数の値を渡すことで、受け取ったメソッドがその値を利用できる。この時点で score 変数には Circle スクリプトから届いている point の値が加算されているため最新状態
    uiManager.UpdateDisplayScore(score);
  }

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

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

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


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


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


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


 以上で設定は完了です。


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


 すべての設定が完了しましたので、ゲームを実行して、キャラをサークルに侵入させて得点を加算してください。
画面のスコア表示がそれに合わせて score 変数の値に更新されれば制御成功です。
Console ビューに score 変数の値が表示されますので画面のスコア表示と照合しましょう。

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


<完成画像>



<実行動画>
https://gyazo.com/bc369da92e00d17bfb879bab324b8a25


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

 次は 手順20 −ゲーム時間の表示制御− です。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

3Dトップビューアクション(白猫風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます