コンテンツにスキップ

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

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

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

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

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

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

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

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

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

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

  1. HierarchyでCanvasを選択した状態で右クリック
  2. UI → Text - 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.csをScoreManagerオブジェクトにドラッグ
  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. メニューから Window → TextMeshPro → Font Asset Creator
  2. Source Font Fileに、入れたフォントを設定
  3. Character Setを Custom 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. ScoreManagerのUpdateTextを書き換える
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.SetInt と PlayerPrefs.GetIntを使うと、 ゲームを閉じても値が残ります)
  • スコアが増えるときに数字がパッと大きくなる演出をつける

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

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

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