i-school - 2D放置ゲーム 手順4
 この手順でユーザーがタップできる場所として「行き先」となるゲームオブジェクトをゲーム画面に配置して設定を行います。
またタップ動作が正常に機能しているかを、Debug.Log メソッドを活用して確認を行い、処理の流れを把握します。


<実装画像>



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


手順4 −行き先の作成−
 6.Canvas内にタップできる地点として行き先用のゲームオブジェクトを配置し、設定する
 7.TapPointDetail スクリプトを作成し、Debug を利用してタップを感知する機能を追加する



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

 ・サマリー機能
 ・TODO 機能
 ・Button.onClick.AddListenerメソッド
 ・SerializeField 属性
 ・Debug.Log メソッドの活用



6.Canvas内にタップできる地点として行き先用のゲームオブジェクトを配置し、設定する

1.設計


 この手順では、Canvas ゲームオブジェクト内にタップ操作を行うための「行き先用のゲームオブジェクト」を製作していきます。
このゲームオブジェクトはゲーム画面に映る必要のあるゲームオブジェクトですので、 Canvas ゲームオブジェクトの子オブジェクトである StageSet の子オブジェクトとしてゲームオブジェクトを作成していきます。

 ここでは、行き先用のゲームオブジェクト群を管理するためのフォルダ役のゲームオブジェクトと、行き先用のゲームオブジェクトの2つを順番に作成し、設計します。


2.StageSet ゲームオブジェクトの子オブジェクトとして TapPointSet ゲームオブジェクトを作成する


 StageSet ゲームオブジェクトの上で右クリックをしてメニューを開き、Create Empty を選択します
新しく空のゲームオブジェクト(Transfrom コンポーネントのみアタッチされている、役割のまだないゲームオブジェクト)が作成されますので、名前を TapPointSet に変更します。
TapPointSet ゲームオブジェクトは、行き先用のゲームオブジェクト群をまとめておくための、フォルダ役のゲームオブジェクトです。


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



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


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



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



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


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


 TapPointSet ゲームオブジェクトの上で右クリックをしてメニューを開き、UI => Button を選択します
Sceneビュー内の中央に、Imgae コンポーネントと Button コンポーネントがアタッチされた白いゲームオブジェクトが新しく作成されますので、名前を btnTapPoint に変更します。


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


btnTapPoint ゲームオブジェクトは、ゲームに登場する行き先の画像の表示とタップできる地点の役割を持ちます。


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



btnTapPoint ゲームオブジェクト Sceneビュー画像(真ん中の白いゲームオブジェクト)



 TapPointSet ゲームオブジェクトの子オブジェクトとして設置されているか、確認した後、次の設定の手順へ移ります。


4.btnTapPoint ゲームオブジェクトの設定を行う


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

 こちらの画像がゲーム画面に適用されるキャラの画像となりますので、無料アセットとしてインポートしたアセット内の画像をこちらに利用します。
なお、色違いの画像もありますので、そちらを利用しても構いません。

パス
Assets/Fantasy Wooden GUI Free/normal_ui_set A/Exclamation_Red.png


フォルダ画像



インスペクター画像



 上記のパスのフォルダ内にある対象の画像ファイルを、Source Image の欄までドラッグアンドドロップしてアサインしてください''。
画像が登録されて、Sceneビューに反映されます。

 画像の設定が終了したら、Image コンポーネントの Raycast Target のスイッチを外してオフにしておいてください



 画像を設定したら、続いて大きさを調整します。

 btnTapPoint ゲームオブジェクトの RectTransfrom コンポーネント内にある、Width と Height の値を (200, 200) に変更してください。
このサイズは、ゲーム画面の大きさを考慮して、自分のゲーム画面に応じたサイズで適宜設定してください。
設定しながら、Gameビューにどのように映っているかを確認しておきます。

 以下に参考画像として、完成状態の画像を掲載します。


btnTapPoint ゲームオブジェクト インスペクター画像(参考値)



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



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



 以上で設定は完了です。
位置については自由な位置に変更していただいて構いません。


7.TapPointDetail スクリプトを作成し、Debug を利用してタップを感知する機能を追加する

1.設計


 行き先用のゲームオブジェクトが完成しましたので、こちらのゲームオブジェクトを制御するためのスクリプトを作成します
このゲームオブジェクトには Button コンポーネントがアタッチされていますので、Unity エディター上ではマウスの左クリック、
スマホ端末上ではタップに反応するようになっています。

 この機能を利用して、ボタン操作を感知して、次の処理へとつなげていくための橋渡しを行う制御を実装します。



 スクリプトの役割は、ゲームオブジェクトやコンポーネントの制御を内部的に行うことにあります。
今回のケースであれば、行き先用のゲームオブジェクトは完成しているものの、ボタンを押されたときに
どのような反応、つまり、処理を行うようにするかは設定されていません。

 この処理の部分にはメソッドを準備して、そのメソッドを実行することで、ボタンが反応して、ゲームが動いているように制御を行います。

 ボタンのタップに反応した場合、行き先を決定確認するウインドウを開くようにしたいのですが、まだそのウインドウはありません。
まずは、ボタンのタップが正常に動作しているかどうかを、Debug.Log メソッドを利用して確認を行う処理を実装します。

 正常に動作していることがわかってから始めて、次の、ウインドウを作成する作業にうつり、ウインドウが完成したら、
この Debug.Log メソッドの部分をウインドウを表示する処理に変更していくようにします。



 このように、Debug.Log メソッドは処理の流れを確認できるという利点から、正常に処理が動くようになっているかを確認する役割も持っています。
事前に処理の流れを把握しつつ、正常に処理が動いていることを確認して次の制御処理を作成していくようにすると、処理の動きを認識出来るようになります。

 一度にすべての処理を作成するのではなく、1つずつ順番に実装を積み重ねて処理を完成させていくことを念頭に置いておいてください。


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


 Project 内にフォルダを作成し、その中にスクリプトを格納します。
フォルダ分けを行う利点としては、今後スクリプトの種類が増えて管理が煩雑になることを未然に防ぐためです。

 Project 内の空いている部分で右クリックをしてメニューを表示し、 Create => Folder を選択します。名前を Scripts に変更します。

 Scripts フォルダ内で再度右クリックをしてメニューを表示し、Create => C# Script を選択します。
Scripts フォルダ内に新しい C# ファイルが生成されますので、名前を TapPointDetail に変更します。

 万が一、ファイル名の変更をする前に名前を決定してしまった場合には、スクリプト内のクラス名を修正することでファイル名とクラス名を同じ名称にしてください。
そうしないとエラーが出てアタッチすることが出来なくなります


TapPointDetail.cs


 スクリプトを作成したらセーブします。Visual Studio のセーブ機能は Ctrl + Shift + S キーです。
ショートカットキーを活用することを徐々に覚えていきましょう。

 次からはスクリプト内で利用されている機能を1つずつ順番に説明します。
この説明が全てではなく、この説明を元に自分で調べることでより深い知識を得ることにつながります。


3.<Summary(サマリー)機能>


 関数(メソッド)やクラスを作成し終わりましたら、必ずその関数やクラスの説明を書くように心がけましょう。書く場所は関数名、あるいはクラス名の1行上の部分です。
半角スラッシュを3個連続で記述すると説明用のコメントであるサマリー(概要)が自動的に記述されます。

    /// <summary>
    /// タップポイントをタップした際の処理    <=  ここが空白で作成されるので、メソッドやクラスの概要を記述する
    /// </summary>
    private void OnClickTapPoint() {
        // 処理
    }

 別の記事で詳しく解説していますので、そちらを確認しておいてください。

 => 知っておきたい豆知識


4.<TODO 機能>


 後々実装を行いたい処理のために、TODO(トゥードゥー) という記述をコメントしておくことで、VisualStudio のタスク管理から一覧表示して確認することが出来るようになります。
書き換える予定の処理や、後で実装を行いたい場所については、この TODO 機能を利用してください。

 詳しい使い方はこちらです。

 => TODO機能


5.<SerializeField 属性>


 変数の宣言に合わせて宣言できる、属性情報と呼ばれるものの1つです。変数の宣言の前に [ ] 付きで書かれた内容が属性情報となります。

 今回利用している属性は SerializeField (シリアライズ・フィールド)という属性情報です。この機能は、インスペクター上に宣言している変数名を表示させる、というものです。

 主に private 修飾子とセットで用いられ、アサインをインスペクター上で可能にするものの、変数の参照先が外部のスクリプトにない(publicの必要がない)場合に利用します。
たとえばButtonコンポーネントやTextコンポーネントといった、インスペクターよりアサインはするものの、その変数の利用先が他のスクリプトにはないようなもの、には利用しやすいです。

 今回はヒエラルキーにある Text 型の情報をアサインできるように宣言しています。


6.<Button.onClick.AddListener メソッド>


 Button コンポーネントには OnClick というイベントを登録する場所があります。ここにゲームオブジェクトのアサインを行うことで、
アサインしたゲームオブジェクトにアタッチされているスクリプトに宣言されている public 修飾子のメソッドを登録することができます。


インスペクター画像



 この処理をスクリプトから制御して追加して行う処理が、onClick.AddListenerメソッドです。引数のない場合と引数のある場合で書式が変化します。

 利点は、private 修飾子のメソッドでも登録できること、スクリプトから登録しているので、Unity内の上記の画像のButton部分への登録作業や、確認をする必要がなくなること、などがあります。

 今回は引数のないメソッドを登録していますので、引数にはそのままメソッド名を記述します。メソッドの()を書くとエラーになるので、メソッド名のみを記述します。

 // ボタンのOnClickイベントに OnClickBattleEnd メソッドを追加する
 btnBattleEnd.onClick.AddListener(OnClickBattleEnd);
 
 コメントにもあるように、この処理はボタンにメソッドを登録するだけですので、メソッド自体の実行処理ではありません。
対象となるボタンを押したときに実行されるメソッドを登録している処理になります。

 詳細については公式のリファレンスを参考にしてください。またネットには記事が多くありますので調べてみましょう。

参考サイト

Unity公式スクリプトリファレンス
Button.on.Click.AddListener
https://docs.unity3d.com/ja/2018.4/ScriptReference...


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


 ヒエラルキーにある btnTapPoint ゲームオブジェクトに対して、作成した TapPointDetail スクリプトをドラッグアンドドロップしてアタッチします。
アタッチを行ったら必ずゲームオブジェクトを選択してインスペクターを確認して、スクリプトがアタッチされているかを確認します。

 インスペクターの TapPointDetail スクリプトを確認します。
SerializeField 属性で宣言してある変数がインスペクター上に表示されていますので、この変数に登録して制御を行うコンポーネントを指定します。
この指定は、制御したいコンポーネントがアタッチされているゲームオブジェクトが対象となります。

 btnTapPoint ゲームオブジェクト自身をドラッグアンドドロップしてアサインしてください。
もしくは、btnTapPoint ゲームオブジェクトのインスペクターから Button コンポーネントを選択してドラッグアンドドロップしてアサインしてください。
どちらの方法でもアサイン出来ます。自動的に、Button コンポーネントがアサインされます。


インスペクター画像



 以上で設定は完了です。


8.<アタッチとアサインについて>


 アタッチアサインという単語があります。これらは似ている言葉ですが、役割は異なります。
正確に把握していないと、先々でつまづいてしまう原因になりますので、しっかりと意味を捉えておきましょう。

 アタッチとは、作成したスクリプト・ファイルやコンポーネントをゲームオブジェクトにドラッグアンドドロップして追加する動作のことです。


<アタッチ>
https://gyazo.com/31b0fb67add402eb9b445c52a45a39b2



 アサインとは、ヒエラルキーにあるゲームオブジェクト、あるいはプレファブ状態のゲームオブジェクトをドラッグアンドドロップして
インスペクターに表示されている変数の場所に、ドラッグアンドドロップしたゲームオブジェクトが持つ情報を登録(代入)する、という動作のことです。


<アサイン>
https://gyazo.com/c8ff760295e9ec1c9e7cb04fc7ad620f


 勘違いしやすいのは、スクリプト・ファイル自体をドラッグアンドドロップして、インスペクターにアサインすることはできません


<間違い>
https://gyazo.com/95c74d487fbaad31e0af1695b9766dfa


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


 すべての実装が終了したらセーブを行い、どのような処理を実装し、どのように動けば正常なのかを把握してから、ゲームを実行します。
ゲーム画面にある btnTapPoint ゲームオブジェクトをマウスの左クリックします。
Console ビューに Debug.Log メソッドに指定した文字列が順番に3つ表示されれば制御成功です。


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


10.<Debug.Log メソッドの活用>


 今回のように、実装したい内容については、事前に処理がそこまで正常に動いているかを確認しておくことが大切です。
そうすることで、次はこの部分に必要な処理を実装していく段階に移ることができます。

 ただしスクリプトの内部的な処理の流れはゲーム画面には表示されませんので、Debug クラスの持つ Log メソッドを活用しましょう。
 
 Log メソッドの引数には文字列や変数を指定し、その値を表示できますので、変数の値や、表示したい文字列を入力しておくことで
処理が正常に期待するように動いている場合には、Console ビューに Log としてこれらの情報が表示されます。

 この機能はエンジニアにとって非常に重要なものであり、プログラムを書く上で欠かせない、ずっと利用していく機能になります。
どの部分にこの Log メソッドを入れれば効果的になるのか、などは、たくさん書いていくことで覚えることができます。

 たくさん書いてみて「この情報は不要」「これが欲しい」というように取捨選択をしていきましょう。
また処理が正常に動いていることが確認できたら、その役割が終了しますので、Log メソッドをコメントアウトするか、処理を削除しておきます。



 以上でこの手順は終了です。
 
 次は 手順5 −ボタンのタップ演出の追加− です。