i-school - スコアとハイスコアの表示をする

設計とロジック


 画面にスコアとハイスコアを表示させるようにします。
 
 Canvasを用意して、そちらにスコアとハイスコアを表示させるTextゲームオブジェクトを用意します。
 Scoreスクリプトを作成し、この中でスコアとハイスコアを変数で管理します。この値をCanvasのTextゲームオブジェクトに送って、画面に表示してもらいます。
 スコアはブロックを破壊すると加算させるようにしたいので、Destroyerスクリプトを修正し、破壊されるときにスコアへ点数を送るようにします。

実装の手順


 実装の手順をまとめます。

1.ヒエラルキー内にUIを追加します。そのUIを利用してスコアとハイスコアを表示します。
2.Scoreスクリプトを作成します。
3.Destroyerスクリプトを修正します。
4.ゲームを実行して、点数が加算され、画面表示が更新されるか確認します。

1.ヒエラルキー内にUIを追加します。そのUIを利用してスコアとハイスコアを表示します。


 ヒエラルキーの create -> UI -> Text を選択して新しいTextオブジェクトを作成します。名前を「ScoreText」に変更します。
「ScoreText」をダブルクリックして配置された位置まで移動し、アンカーを設定後、位置をゲームシーン上で調整します。
ScoreTextを「Duplicate(複製)」して、名前を「ScoreLabel」に変更します。Textの中に「Score : 」と書き込みます。

 新しいCanvasを作り(作成されていなければ)、名前を「ScoreCanvas」に変更します。

 ヒエラルキー内のScoreTextとScoreLabel上で右クリックをして「Duplicate(複製)」を選択して、
名前をそれぞれ「HighScoreText」と「HighScoreLabel」に変更します。
「HighScoreLabel」のTextの中には「HighScore : 」と書き込みます。
「ScoreText」と同じようにそれぞれの位置を調整します。

 ScoreTextとHighScoreTextは、どちらもヒエラルキーのScoreCanvas以下に配置してください。
ScoreCanvas
  ScoreText
  ScoreLabel
  HighScoreText
  HighScoreLabel

のような状態です。




 スコアなどの表示位置は任意です。ゲーム画面に隠れずにユーザーの見えるように配置してください。

参考例

Gameビュー


Sceneビュー



2.Scoreスクリプトを作成します。

 
 Assets -> Scriptフォルダ内で右クリックをして create -> C# scrptを選択します。
名前を「Score」に変更します。
下記のソースコードを書き込みます。

score.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Score : MonoBehaviour {

    // スコアを表示するUIの取得用
    public Text scoreText;
    // ハイスコアを表示するUIの取得用
    public Text highScoreText;

    // スコアのカウント用
    private int score;

    // ハイスコアのカウント用
    private int highScore;

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

    void Start ()
    {
        Initialize ();
    }

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

        // highScoreKeyの値で保存されているハイスコアを検索して取得する。保存されてなければ0を取得する。
        highScore = PlayerPrefs.GetInt (highScoreKey, 0);
    }
    
    // ポイントの追加。修飾子をpublicにしているので外部より参照できるメソッドになっている
    public void AddPoint (int point)      // 外部より受け取ったint型の引数をpointとして受け取る
    {
        score += point;
        
        Debug.Log(score);                       // ここで確認すると、ブロックからの情報が届いているか確認できる。表示されなければ届いていないということになる。
        
        // スコアがハイスコアより大きくなれば、ハイスコアを更新する
        if (highScore < score) {
            highScore = score;

            Debug.Log(highScore);               // ハイスコアの更新が正常に行われたか確認できる
        }

        // ゲーム画面上のスコアとハイスコアの表示を更新する
        DisplayScores();
    }

    // ゲーム画面上のスコアとハイスコアの表示を更新する
  private void DisplayScores(){
        // 現在のスコアとハイスコアを画面に表示する
        scoreText.text = score.ToString ();
        highScoreText.text = highScore.ToString ();
    }

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

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


PlayerPrefsは、データのセーブ・ロードを行う、Unityの用意しているクラスです。
公式リファレンス
https://docs.unity3d.com/jp/current/ScriptReferenc...

現在はまだ動作はしていませんが、ここでは3つの使い方をしています。
まず、データのセーブ・ロード用のキーを設定します。キーの設定はstring型の変数を使用します。
private string highScoreKey = "highScore";
ここで設定をしています。
highScore = PlayerPrefs.GetInt (highScoreKey, 0);
ここでは、highScoreKeyにInt型の変数にデータがセーブされているかどうかを確認し、セーブされていればその数値を取り出してhighScoreへ代入しています。なければ0を代代入しています。
PlayerPrefs.SetInt (highScoreKey, highScore);
ここでは、highScoreKeyにhighScoreの数値を参照しています。この状態を作ることで、次のセーブが出来ます。
PlayerPrefs.Save ();
セットした数値をセーブを実行するメソッドです。

こちらのサイトが詳しいです。
https://freesworder.net/unity-playerprefs/


 このScoreスクリプトをヒエラルキーの「ScoreCanvas」へアタッチします。= ScoreCanvasでScoreの管理をさせます。
ScoreCanvasゲームオブジェクトのインスペクターを確認してください。Scoreスクリプトがアタッチされているとインスペクターに表示されます。

 public修飾子で宣言した変数が2つありますので、アサイン情報を登録出来るようになっています。
それぞれ変数名と同名のゲームオブジェクトをヒエラルキーからドラッグアンドドロップして、対応する箇所にアサインしてください。



3.Destroyerスクリプトを修正します。


 続いて、Boxの方にアタッチされているスクリプトにも変更を加えます。
これはBoxが破壊された際に得点をScoreスクリプトに引き渡すようにする処理を追加します。

 得点用の変数は外部で調整できるように、public修飾子で宣言しています。

Destroyer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Destroyer : MonoBehaviour {
 
    public int point;               <-  追加。インスペクターから点数を登録してください
    public GameObject masterObj;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }

    void OnCollisionEnter(Collision collision) {
    
        //スコア処理を追加
        FindObjectOfType<Score>().AddPoint(point);  <-  追加
    
    masterObj.GetComponent<GameMaster>().boxNum--;
        Destroy(this.gameObject);
    }
}
※ FindObjectOfType<Object>()メソッドは、シーン内の<Object>(ここでは<Score>スクリプト)を参照して、そのスクリプトのAddPointメソッドにアクセスするメソッドです。
対象を特定できる場合には「GetComponent」、不特定な誰かの中から情報を参照して、その個人情報にアクセスする場合には「FindObjectOfType」を利用します。

 新しくpoint変数を追加し、それをBoxが破壊された際にScoreスクリプトのAddPointメソッドへ渡すようにしています。

 修正がおわりましたら、Boxのプレファブを選択し、Open Prefabを選択します。
Destroyerスクリプトのインスペクターに新しく point 変数が追加されていますので、点数を登録してください。


4.ゲームを実行して、点数が加算され、画面表示が更新されるか確認します。