【Unity】カウントアップでリザルト画面にスコアを表示

当サイトで紹介する商品・サービス等の外部リンクは、アフィリエイト広告を含む場合があります。
スポンサーリンク
本記事を読むと以下の実行ができます

敵を倒すとスコアが加算される。

RPGやクイズゲームなどのジャンルでスコアを表示させたい場面は多いことでしょう。例えば、敵を倒すと、当たったらスコアが加算されるように機能があるとゲーム感が増します。

本記事では、画面上にスコアを表示する方法を紹介します。

本記事は次の人におすすめ
  • Unityでスコア表示したい人
  • カウントアップをリアルタイムでしたい人
  • スコアをリザルト画面(別シーンで表示)
Udemyで学習する
スポンサーリンク

スコアを表示するには?

Unityでスコアを表示するには「tostring」メソッドを使用する必要があります。tostringを使うことで、数字を文字列に変換することができます。

例えば、以下のコードのようにstring型にint型を代入すると、エラーが発生します。

//NG

using UnityEngine;

public class Score : MonoBehaviour
{
    int point = 100;
    string score;

    void Start()
    {
        score = point; //文字の型が異なるため
        Debug.Log(score);
    }

}

エラーコード「CS0029」は以下のように言及されています。

型 ‘type’ を ‘type’ に暗黙的に変換できません

コンパイラでは、明示的な変換が必要です。 たとえば、左辺値と同じ型の右辺値をキャストする必要があります。 また、特定の演算子のオーバーロードをサポートするための変換ルーチンを指定する必要があります。

型の変数を別の型の変数に割り当てた場合、変換を行う必要があります。 異なる型の変数間で割り当て行うと、コンパイラで代入演算子の右辺の型を代入演算子の左辺の型に変換する必要があります。 次のコードを実行します。

コンパイラ エラー CS0029 – C# reference

UnityではなくC#での解説ですが、引用文を分かりやすくいうと代入する型を揃える必要があります。今回スコアを表示することが目的なので、int型をstring型に代入します。

「tostring」メソッドは数字を文字に変換したいときに使用しコンパイルエラーを解決することができます。

//OK
score = point.ToString(); 

//NG
score = point; 

変数や定数の型に「.Tostring」とつけるだけで文字列と扱うことができます。試しにコンパイルしてみると、目的通りスコアを表示することができました。

敵を倒すとスコア加算し、リザルト画面で表示

Tostringを使用した応用として敵を倒してスコアをカウントアップしていき、全てのモンスターを倒したら画面を移動してリザルト画面を表示(別シーンに移動)します。

敵の画像を左クリックすると、敵が消滅してスコアに加算されます。すべて倒し終わったらゲーム終了になります。

使う機能
  • Tostringでスコア表示(本記事)
  • 画面遷移でプレイ画面からリザルト画面
  • 左クリックで敵を倒す

ソースコード1

このスクリプトは各敵にそれぞれアタッチして下さい。

using UnityEngine;
using UnityEngine.EventSystems; // IPointerClickHandler 使用のため

public class Enemy : MonoBehaviour, IPointerClickHandler
{
    // 通常1回、ボスなら3回など調整
    public int clickCountNeeded = 1;
    // 撃破時に加算されるスコア
    public int scoreValue = 100;
    private bool isDefeated = false;

    // UIの画像(Image)がタッチ/クリックされた際に呼ばれる
    public void OnPointerClick(PointerEventData eventData)
    {
        if (isDefeated) return;

        clickCountNeeded--;
        Debug.Log("Life:"+clickCountNeeded);

        if (clickCountNeeded <= 0)
        {
            DefeatEnemy();
            Debug.Log("Defeat!");
        }
    }

    private void DefeatEnemy()
    {
        isDefeated = true;
        GameManager.instance.AddScore(scoreValue);
        Destroy(gameObject);
    }
}

解説1

  • 名前空間

「UnityEngine」:ゲームオブジェクト操作、コンポーネント制御の基本的な機能を使用するために必要になります。

UnityEngine.EventSystems」:IPointerClickHandlerインターフェースを用いて、UI要素のクリックやタッチのイベント処理を行うために必要です。

  • フィールド(メンバ変数)

「clickCountNeeded」:敵を倒すのに必要なクリック回数を設定するための変数。例えば通常の敵なら1回、ボスならば3回など、敵ごとに設定可能です。

「scoreValue」:敵を撃破した際にプレイヤーに加算されるスコアを格納する変数。敵によって変数の値を設定可能です。

「isDefeated」:敵がすでに撃破済みかを判定するためのフラグ。trueになると以降のクリックを無効にし、処理を重複させないです。

  • OnPointerClickメソッド

敵のUI画像(Image)がクリックまたはタッチされるたびに呼び出されるメソッド。

マウスのクリックで処理する方法を紹介しています。

まず、敵がすでに倒されている場合は何もせず処理を終了します。倒されていなければ、clickCountNeededを1減らし、敵の残りライフをDebug.Logに出力します。

clickCountNeededが0以下になるとDefeatEnemyメソッドを呼び出し、撃破の処理を実行します。

  • DefeatEnemyメソッド

敵の撃破時に呼び出されるメソッド。

初めに、isDefeatedをtrueに設定して敵が倒されたことを明示します。GameManagerのスコア加算機能を呼び出し、プレイヤーのスコアをscoreValue分増加させます。

最後に敵のゲームオブジェクトを削除して画面から消去します。

UdemyでUnityを学習

Udemyは、オンデマンド式の学習講座です。
趣味から実務まで使えるおすすめの講座を紹介します。

\Unityの学習から収益化の方法はこちらから!/



ソースコード2

このスクリプトはゲーム操作のシステムになります。

using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour {
    public static GameManager instance;

    public int score = 0;
    // TMPのTextMeshProコンポーネント(Inspectorから設定)
    public TMP_Text scoreText;
    // リザルトシーンの名前(Hierarchyのシーン名と一致させ、Build Settingsに追加すること)
    public string resultSceneName = "ResultScene";

    // シングルトンパターンの実装
    private void Awake() {
        if (instance == null) {
            instance = this;
            // シーン遷移時にGameManagerオブジェクトを破棄させない場合は以下を有効化
            // DontDestroyOnLoad(gameObject);
        } else {
            Destroy(gameObject);
        }
    }

    // 敵が撃破された際に呼び出されるスコア加算メソッド
    public void AddScore(int value) {
        score += value;
        UpdateScoreUI();
        CheckAllEnemiesDefeated();
    }

    // TMPテキストを利用してスコアUIの更新
    private void UpdateScoreUI() {
        scoreText.text = score.ToString();
    }

    // 全ての敵が撃破されているかをチェックし、撃破済みであればリザルトシーンへ遷移
    private void CheckAllEnemiesDefeated() {
        // タグ「Enemy」を付けたオブジェクトをすべて取得
        GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
        if (enemies.Length == 0) {
            // すべての敵が除去されたのでリザルトシーンへ切り替
            SceneManager.LoadScene(resultSceneName);
        }
    }
}

解説2

  • 名前空間

TMPro」:TextMeshPro(TMP)のUIコンポーネントを利用し、画面上のスコア表示を管理するために必要。

UnityでTextMeshProの使い方を紹介しています。

UnityEngine.SceneManagement」:ゲーム内でシーンを切り替える機能(シーン遷移)を使用するために必要。

シーン遷移について紹介しています。
  • フィールド(メンバ変数)

「instance」:GameManagerをシングルトンパターンとして実装するための静的インスタンス変数。他スクリプトから容易にアクセスできます。

「score」:プレイヤーの現在のスコアを保持する整数型変数。

「scoreText」:スコアを画面に表示するためのTextMeshPro(TMP)コンポーネントを格納する変数。インスペクター経由で割り当てます。

「resultSceneName」:ゲーム終了時に表示するリザルトシーン名を格納する変数。HierarchyとBuild Settingsの登録名と一致させる必要があります。

  • Awakeメソッド

シーンがロードされた時点で最初に1回だけ呼ばれます。
GameManagerクラスをシングルトンパターンで実装するための処理を行います。

もしinstanceが未設定(null)ならば、現在のインスタンスをinstanceに設定します。(DontDestroyOnLoadをコメントアウト解除すればシーン間で永続化も可能)
既にinstanceが存在している場合は、新しく生成されたGameManagerを削除し、重複を防止します。

  • AddScoreメソッド

敵が撃破された際に呼ばれるメソッド。

渡された引数(value)をスコアに加算した後、画面のスコアUIを更新します(UpdateScoreUIメソッド呼び出し)。さらに、全ての敵が撃破されているかをCheckAllEnemiesDefeatedメソッドで判定します。

  • UpdateScoreUIメソッド

スコアが更新された際に呼び出され、TMPテキストを用いてUI上のスコア表示を現在のスコア値に更新します。

  • CheckAllEnemiesDefeatedメソッド

シーン内で「Enemy」タグを持つ全てのオブジェクトを取得し、敵が残っているか確認します。
もし敵がすべて倒されており、一体も存在していなければ、リザルトシーン(resultSceneNameで指定したシーン)へ遷移します。

実演

これら2つのスクリプトをアタッチしてください。また、敵キャラにタグ「Enemy」を添付しタグを有効にしてください。

ゲームを再生すると、冒頭で紹介したように左クリックで敵に攻撃することができます。通常敵は1回、ボスは3回クリックで倒すことができます。また、スコアをカウントアップさせて「Tostring」メソッドで画面上にスコアを表示しています。

まとめ

本記事では、「Tostring」メソッドでスコアを表示させました。敵を倒すとスコアが加算されてリザrと画面に表示します。

その他にも当たったらスコア表示やランキングを導入するとゲームの質が向上します。

Udemyで学習する
タイトルとURLをコピーしました