コンテンツにスキップ

第10週:スコアを表示しよう

前回はOnCollisionEnter2Dで合体処理を作りました。

  • 相手が玉かどうかはGetComponent<Ball>()で判定
  • 両方の玉で呼ばれるので、片方だけが処理するようにした
  • mergedの印で二重処理を防いだ

今日はスコアを画面に表示します。

  • CanvasとUIの仕組みを理解する
  • TextMeshProで文字を画面に出す
  • スコアを管理するスクリプトを作る
  • 合体したら点が入るようにする

スコア表示のような文字は、玉や壁とは違う扱いになります。

ゲーム世界のもの UI
玉、壁、床 スコア、ボタン
置く場所 シーンに直接 Canvasの中
カメラが動くと 一緒に動く 動かない(常に画面に固定)
座標 Transform RectTransform(画面上の位置)
  1. Hierarchyで右クリック
  2. UICanvasを選択
  3. HierarchyにCanvasEventSystemの2つができる
Canvasの作成
Canvasの作成

このままだと、画面の大きさが変わったときに文字の大きさがずれます。

  1. HierarchyでCanvasを選択
  2. InspectorのCanvas Scalerを見る
  3. UI Scale ModeScale With Screen Sizeに変更
  4. Reference ResolutionX: 1920, Y: 1080にする

Unityで文字を表示する部品です。 昔からあるTextより文字がきれいで、 拡大してもぼやけません。今はこちらが標準です。

  1. HierarchyでCanvas選択した状態で右クリック
  2. UIText - TextMeshProを選択

初めてTextMeshProを使うと、ウィンドウが出ます。

  1. 「Import TMP Essentials」ウィンドウが表示される
  2. Import TMP Essentialsボタンをクリック
  3. 完了したらウィンドウを閉じる
  4. もう一度 UI → Text - TextMeshPro でテキストを作る
TMP Essentialsのインポート
TMP Essentialsのインポート
  1. できたオブジェクトの名前をScoreTextに変更(F2キー)
  2. InspectorのRectTransformで位置を設定:
    • Anchor Presets(左上の四角いボタン)をクリック
    • 左上を選択
    • Pos X:150、Pos Y:-60
    • Width:400、Height:80
  3. TextMeshPro - Textの設定:
    • Text Input欄にSCORE 0と入力
    • Font Size:48
    • Vertex Color:白(背景が暗ければ白、明るければ黒)
    • Alignment:左寄せ
スコア表示の設定
スコア表示の設定

スコアはゲーム全体で1つの数字です。 玉に持たせると、玉が消えたときに一緒に消えてしまいます。

そこで専用の係のオブジェクトを作って持たせます。

  1. Hierarchyで右クリック → Create Empty
  2. 名前をScoreManagerに変更
  1. Assets/Scriptsを右クリック
  2. Create → MonoBehaviour Script
  3. 名前をScoreManagerにする
using UnityEngine;
using TMPro;
public class ScoreManager : MonoBehaviour
{
// どこからでも呼び出せるようにするための入口
public static ScoreManager instance;
// スコアを表示するテキスト
public TextMeshProUGUI scoreText;
// 現在のスコア
private int score = 0;
void Awake()
{
// 自分を入口に登録する
instance = this;
}
void Start()
{
UpdateText();
}
// 点を足す(他のスクリプトから呼ばれる)
public void AddScore(int points)
{
score += points;
UpdateText();
}
// 表示を書き換える
void UpdateText()
{
scoreText.text = "SCORE " + score;
}
}
  1. ScoreManager.csScoreManagerオブジェクトにドラッグ
  2. HierarchyでScoreManagerを選択
  3. InspectorのScore Text欄に、 HierarchyのScoreTextをドラッグ
ScoreManagerの設定
ScoreManagerの設定

玉が合体したとき、玉のスクリプトから ScoreManagerに点を足してもらう必要があります。

でも玉はScoreManagerがどこにいるか知りません。

前回作ったBallスクリプトの、合体する部分に追加します。

// 両方に「合体した」印をつける
merged = true;
other.merged = true;
// スコアを足す(番号が大きいほど高得点)
if (ScoreManager.instance != null)
{
ScoreManager.instance.AddScore(level * 10);
}
// 2つの真ん中の位置を計算
Vector3 center = (transform.position + other.transform.position) / 2f;

AddScore(level * 10)なので、こうなります。

合体した玉 計算 得点
レベル1同士 → レベル2 1 × 10 10点
レベル2同士 → レベル3 2 × 10 20点
レベル3同士 → レベル4 3 × 10 30点
レベル4同士 → レベル5 4 × 10 40点
レベル5同士 → レベル6 5 × 10 50点

再生して玉を合体させてください。

左上のスコアが増えます!

スコアが増える画面
スコアが増える画面

なぜそのままでは表示できないのか

Section titled “なぜそのままでは表示できないのか”

初期状態のフォントは英数字用なので、 日本語を入れると□□□(豆腐)になってしまいます。

日本語を出すには、日本語のフォントアセットを作る必要があります。

手順1:フォントファイルを用意する

Section titled “手順1:フォントファイルを用意する”
  1. Google Fonts(https://fonts.google.com/noto/specimen/Noto+Sans+JP) からダウンロード
  2. Assets/Fontsフォルダを作り、 フォントファイル(.ttf)をドラッグ

手順2:フォントアセットを作る

Section titled “手順2:フォントアセットを作る”
  1. メニューから WindowTextMeshProFont Asset Creator
  2. Source Font Fileに、入れたフォントを設定
  3. Character SetCustom Charactersに変更
  4. Custom Character Listに、使う文字を全部入力
    (例:スコアゲームオーバーもう一度あそぶ0123456789
  5. Generate Font Atlasをクリック
  6. SaveをクリックしてAssets/Fontsに保存
Font Asset Creatorの画面
Font Asset Creatorの画面
  1. ScoreTextを選択
  2. Font Asset欄に、作ったフォントアセットをドラッグ
  3. ScoreManagerUpdateTextを書き換える
void UpdateText()
{
scoreText.text = "スコア " + score;
}
症状 原因と対処法
テキストが画面に出ない Canvasの子になっていない。Canvasの中にドラッグ
文字が□□□になる 日本語フォントが未設定。英語表記にするかフォントアセットを作る
TMPro not foundのエラー using TMPro;を書き忘れている
スコアが増えない BallにAddScoreの呼び出しを追加したか確認
NullReferenceException ScoreManagerのScore Text欄が空
文字が小さすぎる/大きすぎる Font Sizeを調整。Canvas ScalerのReference Resolutionも確認
テキストが見切れる RectTransformのWidthとHeightを大きくする
文字が玉の後ろに隠れる UIは常に手前に出る。隠れるならCanvasの外にある

基礎課題全員必須

スコアを表示する:

  • CanvasとScoreTextを作る
  • ScoreManagerオブジェクトとスクリプトを作る
  • InspectorでScore Textを設定する
  • BallスクリプトからAddScoreを呼ぶ
  • 合体したらスコアが増えることを確認
  • 最後にCtrl + Sで保存する

標準課題時間があれば

表示を工夫する:

  • 得点の計算をlevel * level * 10に変えて 遊びやすさを比べる
  • 合体した回数も表示する(変数とテキストを追加)
  • 文字の色や大きさ、位置を調整して見やすくする

発展課題チャレンジ

ハイスコアと日本語表示:

  • 日本語フォントアセットを作り、「スコア」と表示する
  • ハイスコアを記録して表示する
    (ヒント:PlayerPrefs.SetIntPlayerPrefs.GetIntを使うと、 ゲームを閉じても値が残ります)
  • スコアが増えるときに数字がパッと大きくなる演出をつける

スコアが出てゲームらしくなりました。

でも今のままではいつまでも終わりません。 次回は制限時間をつけて、時間切れで終わるようにします。 もう一度遊ぶボタンも付けます。

制限時間があると、同じ条件でスコアを競えるようになります。