【Unity】スコアの表示：「はじめてのUnity」のブロック崩しを改造しながら学ぶ

# はじめに
JunShimuraさんの「[[超初心者向け]Unityチュートリアル「はじめてのUnity」のブロック崩しと同等をC#で](http://qiita.com/JunShimura/items/cbb0db8087a5cc75735e) ::(1)ステージ配置～(6)ブロックを手作業で並べる)」をよりゲームらしく改造する。

作成する記事は下記の通りです。

 * スコアの表示(この記事)
 * [ゲームマネージャークラスを作る](http://qiita.com/yaju/items/5a3b46104f4f0a767c7f)
 * [ブロックをスクリプトで配置](http://qiita.com/yaju/items/5b54016c6574bc84c41d)
 * [音を鳴らす](http://qiita.com/yaju/items/32a6960a2e61267f8731)

# スコアの表示
スコアの表示はScene上はカメラの影響で傾いて表示されますが、実際のGame上は垂直に表示されます。
![Unity_ScoreScene.png](https://qiita-image-store.s3.amazonaws.com/0/14053/2a17fded-60b2-1703-9f61-2db1d51b3ce0.png)

![Unity_ScoreGame.png](https://qiita-image-store.s3.amazonaws.com/0/14053/307fa613-f682-dcf7-60f4-12d578412677.png)

## テキストの追加
メニューの[GameObject]>[UI]>[Text]を選択して下さい
![Unity_TextAdd.gif](https://qiita-image-store.s3.amazonaws.com/0/14053/da6f0a61-47aa-0bf9-dad7-250c47568e52.gif)

## Canvasの設定変更(Score GUI)
Canvasの[Inspector]タブにて名前を「Score GUI」にします。Canvasコンポーネントにある`Render Mode`を`Screen Space - Camera`に変更します。次に`Render Camera`のところにある○をクリックし、開いたリスト画面から`Main Camera(Camera)`を選択します。

![Unity_ScoreGUI.gif](https://qiita-image-store.s3.amazonaws.com/0/14053/e5296c18-3f84-6ad9-0f61-b8dc3f524d05.gif)

※Canvasの`RenderMode`のデフォルトが`Screen Space - Overlay`になっているのですが、初心者に操作させるのは難しいので、今回は`Screen Space - Camera`にしています。
`Screen Space - Overlay`はゲームで使われる他のオブジェクトの描画が終わったあとにGUIが描画されます。つまりGUIが絶対に最前面になります。本来はこれが望ましいです。その場合、Scene上ではGUIが別の位置に配置されますが、Game上では重なって表示されます。CanvasをクリックすればScene上のGUI位置に移動するので、慣れればこちらを使う方がいいかも知れません。


## スコアラベルの作成(Score Label)
`Score GUI`配下のTextの[Inspector]タブにて名前を「Score Label」にします。
[Rect Transform]を下図のように変更します。次に`Text`を`Score`と入力します。`Font Style`を`Bold`、`Font Size`を`48`にして`Color`を白(255,255,255)にします。

![Unity_ScoreLabel.png](https://qiita-image-store.s3.amazonaws.com/0/14053/ca053fc9-97c5-8361-c262-2e57ab86c30f.png)

## スコアの作成(Score)
得点をセットするTextを作成します。
`Score Label`を選択して、右クリックメニューの`Duplicate`で複製します。ついでに`EventSystem`は使わないので右クリックメニューの`Delete`で削除しておきます。

![Unity_HieScore.png](https://qiita-image-store.s3.amazonaws.com/0/14053/3dad6b84-9c93-8315-64fb-648bdbed8227.png) -> ![Unity_HieScore2.png](https://qiita-image-store.s3.amazonaws.com/0/14053/5af6fdab-f147-1d14-3852-084acc3b120a.png)

複製時の`Score Label(1)`を[Inspector]タブにて名前を「Score」にします。
[Rect Transform]を下図のように変更します。次に`Text`を`0`と入力します。`Alignment`を右寄せにします。
![Unity_Score2.png](https://qiita-image-store.s3.amazonaws.com/0/14053/408b9dad-1b3a-eca2-8e59-47d4fdb3e064.png)


## ハイスコアの作成
`Score Label`と`Score`の2つを選択した状態で、右クリックメニューの`Duplicate`で複製して`HighScore Label`と`HighScore`を作成します。

![Unity_HieScore3.png](https://qiita-image-store.s3.amazonaws.com/0/14053/3578054f-43cd-2f08-903e-5a4bbbd6e7b9.png)

複製時の`Score Label(1)`を[Inspector]タブにて名前を「HighScore Label」にします。[Rect Transform]を下図のように変更します。
![Unity_HighScoreLabel.png](https://qiita-image-store.s3.amazonaws.com/0/14053/23daab3e-eb63-f3dd-6f3e-bc63e6974e7c.png)
次に`Text`を`High-Score`と入力します。
![unity_HighScoreText.png](https://qiita-image-store.s3.amazonaws.com/0/14053/9fb4ecea-6876-49b4-964c-5f99f6a56be3.png)

複製時の`Score(1)`を[Inspector]タブにて名前を「HighScore」にします。[Rect Transform]を下図のように変更します。
![Unity_HighScore2.png](https://qiita-image-store.s3.amazonaws.com/0/14053/80ec7eab-ed03-b926-fabd-62d52e363fc3.png)


# スクリプトの作成
`Score GUI`の[Inspector]タブの一番下にある[Add Compornent]ボタンをクリックして、Scriptアセットを作成、追加します。ファイル形式はcsを選びます。
![Unity_ScoreAddScript.gif](https://qiita-image-store.s3.amazonaws.com/0/14053/902fac5b-8420-07be-da1d-a472b2d7936c.gif)

ファイル名を`Score`とします。そうすると、Assetsの中に「Score.cs」が出来ています。
※先頭は英大文字です。間違えた場合、ファイル名と中身のクラス名の両方を修正してください。
![Unity_AssetScore.png](https://qiita-image-store.s3.amazonaws.com/0/14053/4376b334-f2ad-23bb-fec8-0fb5f0b71d80.png)

## Score.csを編集する
Assets内の`Score`スクリプト(C#のアイコン）をダブルクリックすると、エディタが開きます。
優先的に開かれるエディタは、多くの場合はMonoDevelopというソフトが起動されます。

今回のスコアのスクリプトは、Unityチュートリアルの「[第12回 Waveを5個にする、スコアの実装](https://github.com/unity3d-jp-tutorials/2d-shooting-game/wiki/%E7%AC%AC12%E5%9B%9E-Wave%E3%82%925%E5%80%8B%E3%81%AB%E3%81%99%E3%82%8B%E3%80%81%E3%82%B9%E3%82%B3%E3%82%A2%E3%81%AE%E5%AE%9F%E8%A3%85)」を参考にしています。

少し長いのでコピー＆ペーストで入力してしまいましょう。
※MonoDevelopでペーストが効かないに時はMonoDevelopを閉じ直してください。

``` csharp:Score.cs
using UnityEngine;
using UnityEngine.UI;

public class Score : MonoBehaviour {

	// スコアを表示する
	public Text scoreText;
	// ハイスコアを表示する
	public Text highScoreText;

	// スコア
	private int score;

	// ハイスコア
	private int highScore;

	// PlayerPrefsで保存するためのキー
	private string highScoreKey = "highScore";

	void Start ()
	{
		Initialize ();
	}

	void Update ()
	{
		// スコアがハイスコアより大きければ
		if (highScore < score) {
			highScore = score;
		}

		// スコア・ハイスコアを表示する
		scoreText.text = score.ToString ();
		highScoreText.text = highScore.ToString ();
	}

	// ゲーム開始前の状態に戻す
	private void Initialize ()
	{
		// スコアを0に戻す
		score = 0;

		// ハイスコアを取得する。保存されてなければ0を取得する。
		highScore = PlayerPrefs.GetInt (highScoreKey, 0);
	}

	// ポイントの追加
	public void AddPoint (int point)
	{
		score = score + point;
	}

	// ハイスコアの保存
	public void Save ()
	{
		// ハイスコアを保存する
		PlayerPrefs.SetInt (highScoreKey, highScore);
		PlayerPrefs.Save ();

		// ゲーム開始前の状態に戻す
		Initialize ();
	}
}
```

## ScoreとHighScoreを設定する
スクリプト内でpublicにした型はInspectorに表示されます。
![Unity_ScoreAddText.png](https://qiita-image-store.s3.amazonaws.com/0/14053/4339d178-c06f-c794-b646-7f91b144c707.png)

ここにスコアとハイスコアを表示するTextコンポーネントをセットします。`Score Text`の右横にある○をクリックし、開いたリスト画面から`Score`を選択します。
![Unity_ScoreText.png](https://qiita-image-store.s3.amazonaws.com/0/14053/805f8483-e2a9-dcba-0de5-c9b443c9633d.png)

`High Score Text`も同様にします。
![Unity_ScoreAddText2.png](https://qiita-image-store.s3.amazonaws.com/0/14053/df881785-87ae-8f1d-b1b3-802acf4efd7f.png)

# スコアを実装する
## Block.csを編集する
得点を入るのはブロックが削除されたタイミングとなりますので、`Block.cs`を編集します。
「FindObjectOfType<Score>().AddPoint(10);」の部分を追加します。

``` csharp:Block.cs
void OnCollisionEnter(Collision collision) {
	//衝突判定
	if (collision.gameObject.tag == "Ball") {
		//スコア処理を追加
		FindObjectOfType<Score>().AddPoint(10);

		//相手のタグがBallならば、自分を消す
		Destroy(this.gameObject);
	}
}
```
これでブロックがボールに当たったときにスコアに10点が加算されるようになります。

## FindObjectOfType＜スクリプト＞
他スクリプトのアクセス(値参照/メソッド呼出)方法として、今回FindObjectOfType関数を使っています。対象コンポーネントが1つしか使用されないことが確定している場合に使用するといいでしょう。

# 実装を確認する
エディタ画面中央の実行ボタンを押してみましょう。
ブロックがボールに当たったときにスコアに10点が加算するのが確認されます。またハイスコアも変更されているのが確認できるでしょう。

![Unity_ScoreAddGame.png](https://qiita-image-store.s3.amazonaws.com/0/14053/a61ac7bf-eb97-7a11-44a4-9bf937d6954f.png)

ちなみに実行を終了し再実行しても、ハイスコアは初期値に戻ってしまいます。これはハイスコアの保存(Save)の処理を呼んでいないためです。
ハイスコアの保存を実装するとしたら、ゲームオーバー時になりますので次回に組み込みます。

# 学んだこと
* uGUIのTextコンポーネントを使って文字を表示できること
* スクリプトでPublic変数に定義したものをInspectorでセットできること
* 他スクリプトからメソッドの呼び出しができること
* PlayerPrefsクラスを使用してハイスコアを保存できること

# 参照
* [UnityとBlenderハンズオン第7章](https://www.slideshare.net/yaju88/unityblender7)
* [UnityとBlenderハンズオン第8章](https://www.slideshare.net/yaju88/unityblender8)
* [UnityとBlenderハンズオン第9章](https://www.slideshare.net/yaju88/unityblender9)
* [UnityとBlenderハンズオン第10章](https://www.slideshare.net/yaju88/unityblender10-55356833)