前回はbarとballの当たり判定をしてballがbarに当たったらballを消去しました.今回はさらにballがbarに当たった時にスコアが増えるようにしたいと思います.さらにはボールを取り逃がしたらゲームオーバーという表示が出るようにもしましょう.今回で2Dのボールキャッチゲーム制作は終了です.しっかり身につけましょう.
さて,スコアを表示するにはテキストを表示する必要があります.そのためにはHierarchyビューの+マークをクリックして[UI]→[Text]を選択します.するとHierarchyにCanvasとEventSystemができ,Canvasの下にTextができます:
ただし,このままだとテキストを表示するCanvasがMain Cameraの表示領域を大きくはみ出していますのでまずこれを調整します.
HierarchyビューでCanvasを選択し,InspectorのCanvasでRender ModeをScreen Space - Cameraを選択し,HierarchyビューのMain CameraをInspectorのCanvasにあるRender Cameraにドロップします: 次にHierarchyビューでCanvasの矢印をクリックして下の階層から出てきたTextを選択します.Inspectorの中からTextを見て「New Text」と書かれたテキストエリアをクリックして「スコア」を入力します:
次にこのままだと背景色と一緒で文字が見えませんのでColorの右側の色の表示窓をクリックして色を変えます.外側の円で色相を変え内側の正方形でその色相の色の明るさや彩度の異なる色を最終的に選択します.今回はスコアを赤色に設定してみました.正確に決めたい場合はRGBの値をそれぞれ調節して入力します.なおAは透過の設定になります.決まったらウィンドウの×ボタンをクリックしてください:
Sceneビューで正方形の領域の左下側の横長の長方形内に小さくスコアと表示されるので,この長方形の四つの辺のどれかの上でカーソルが↔や↕に変わったところでその辺をドラッグして表示領域を大きくします.また表示領域の内側をドラッグすると位置を移動できますので画面右上に移動してください.それから再びInspectorでCharacterからFont Sizeを大きくします.今回は30に設定することにします.なお文字が表示領域に収まらない場合,全く表示されなくなってしまう場合がありますので,何も表示されない場合は,
- 表示領域を大きくするかFont Sizeを小さくする
- 文字色が背景の色と似ている場合は変える
- Font Sizeが極端に小さくて実際には表示されているが見落としていないか確認する
のいずれかの場合が考えられますのでご注意ください.またInspctor直下のTextと表示されているテキストオブジェクトの名前をScoreにします.このオブジェクト名が,スコアを更新したときに表示するテキストオブジェクトの名前になりますので,入力ミスには気を付けてください.以上が終わると次のような画面になります:
さらにゲームオーバーのときのテキストも追加しましょう.HierarchyビューのCanvasを右クリックして,[UI]→[Text]を選択します.Canvasの下に新たにTextが現れますのでクリックしてInspectorでオブジェクト名をEndingとし先ほどと同じようにして画面中央に大きな表示領域を作り,テキストの内容にゲームオーバーと書いてFont Sizeを大きく設定し,文字色も再び赤にしましょう:
ただし,Textとして表示させている「ゲームオーバー」の文字はいったん全部削除して消してしまいましょう.というのもこのままPlayボタンを押してみればわかるのですが,このままではゲーム開始直後からゲームオーバーの文字が表示されてしまうからです.そのため,表示するのはボールをキャッチし損ねた時にスクリプトで表示するためです.それでは何のために一度入力したかというと正常に表示されるかどうかの確認の為に一度入力してみました.
今度はこれらのテキストの表示に使ったCanvasに得点を加算するスクリプトとゲームオーバーの文字を表示するスクリプトを追加しましょう.ProjectビューのAsssetsフォルダ内を右クリックし,[Create]→[C# Script]を選択し,できたファイルをTextControllerに変えます.そして次のコードを入力してください:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class TextController : MonoBehaviour { int score = 0; GameObject scoreText; GameObject endingText; public void Ending() { this.endingText.GetComponent<Text>().text = "ゲームオーバー"; } public void AddScore() { this.score += 8; } // Start is called before the first frame update void Start() { this.scoreText = GameObject.Find("Score"); this.endingText = GameObject.Find("Ending"); } // Update is called once per frame void Update() { scoreText.GetComponent<Text>().text = "スコア:" + score.ToString(); } }
このスクリプトはフィールドで整数スコアを0で初期化し,フィールドで定義したscoreTextとendingTextという空のGameObjectにそれぞれScoreとEndingという名前で登録したCanvasの下のTextObjectをスタート時に代入しています.なお,Findメソッドはかなり処理が重いので,なるべくスタート時に設定し,Update()メソッド内には記述しない方が良いでしょう.また,scoreはAddScoreメソッドが実行されるたびに8点づつ加算されますので,このメソッドは衝突判定の中で衝突するたびに1回ずつ実行してやる必要があります.そしてこのスコアが,Updateメソッド内でscoreTextの表示内容に先頭の文字を"スコア:"として数字で表されることになります.またEndingメソッドは衝突せずに画面外に出たballができた時に実行され,endingTextに"ゲームオーバー"と表示されます. そこでこのスクリプトを保存したら,今度はProjectビューのAssetsフォルダからbarControllerのスクリプトをダブルクリックし以下のように追加します:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class barController : MonoBehaviour { GameObject canvas; // Start is called before the first frame update void Start() { this.canvas = GameObject.Find("Canvas"); } // Update is called once per frame void Update() { if (Input.GetKey(KeyCode.LeftArrow) && transform.position.x > -4) { transform.Translate(-0.1f, 0, 0); } if (Input.GetKey(KeyCode.RightArrow) && transform.position.x < 4) { transform.Translate(0.1f, 0, 0); } } void OnTriggerEnter2D(Collider2D collider) { canvas.GetComponent<TextController>().AddScore(); Destroy(collider.gameObject); } }
これも保存したら,先ほど作成したTextControllerをcanvasにアタッチします.Hierarchyビューのcanvasをクリックした状態で,ProjectビューのAssetsフォルダ内のTextControllerスクリプトをドラッグしてcanvasにドロップします.するとcanvasにTextControllerがアタッチされますので,早速Playボタンを押してゲームを実行してみましょう:
最後にbarがballをキャッチし損ねた時,ゲームオーバーと表示してbarを消してみましょう.
ProjectビューのAssetsフォルダでballControllerスクリプトをダブルクリックして以下のコードを追加します:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ballController : MonoBehaviour { GameObject bar; GameObject canvas; // Start is called before the first frame update void Start() { bar = GameObject.Find("bar"); canvas = GameObject.Find("Canvas"); } // Update is called once per frame void Update() { transform.Translate(0, -0.1f, 0); if (transform.position.y < -5) { canvas.GetComponent<TextController>().Ending(); Destroy(bar); Destroy(gameObject); } } }
これでボールをバーがキャッチし損ねるとゲームオーバーの文字が表示されバーが画面から消えるようになりました!
これで2Dのボールキャッチゲームが完成しました.やったね!
4回にわたって2Dのボールキャッチゲームを製作しましたが今回で完成しました.途中画面の外にテキストがはみ出たり,Unityのレイアウトが環境によって各ビューの配置が異なったりするかもしれません.その際は適宜見た目を基準にして調整してください.細かく数字を調整して合わせる技術も画面全体にタイルを敷き詰めたりする際には重要ですが,ここでは比較的"ユルく"見た目の感じを大事にしてやりました.いろいろ微調整をやりながら一番うまくいくやり方でやってみてください.応援しています!
次回からはいよいよ3Dのゲーム制作の話に入ります.3Dは2Dと違ってずっと難しいんじゃないの?と思われた方も多いと思いますが,大丈夫.カメラの操作が複雑になる以外は2Dとほとんど一緒です.逆にカメラが難しいので先に2Dから説明しました.次回から制作するのは今度は3D版のボールキャッチゲームです.でも3Dになるだけでなんかワクワクしませんか?
こうご期待!