Unity初心者がクイズゲームを作ります。
第5回は何問中何問正解したかという結果の表示画面を作ります。また、累計の成績を表示するために、成績データのセーブとロード機能も入れます。
- Mac mini (M1, 2020)
- Unity 2022.3.36f1
結果画面の表示
クイズを終了したときに最後に表示される結果画面を作ります。今回のゲームで何問中何問正解したかの正解数と正解率を表示します。
正解数をカウントする
QuizController.csに以下のコードを追加します。
public class QuizController : MonoBehaviour
{
// ...省略...
public int correctAnswerCount = 0; // 正解数
// ...省略...
// 答え合わせを遅らせるコルーチン
IEnumerator DelayAnswer(int selectedIndex)
{
// ...省略...
if (isAnswerSelected)
{
// 答え合わせ処理
if (selectedIndex == correctAnswerIndex) // 正解だったら
{
// ...省略...
correctAnswerCount++; // 正解数を増やす
}
else // 不正解だったら
{
// ...省略...
}
// ...省略...
}
}
}
正解数を入れておく変数correctAnswerCount
を定義して、正解したら値を1増やします。
結果画面の表示
ResultController.csに以下のコードを追加します。
// ...省略...
using TMPro; // TMPを使う場合に追加
using UnityEngine.UI; // UIを使う場合に追加
public class ResultController : MonoBehaviour
{
// ...省略...
public TextMeshProUGUI correctNumberText; // 正解数のテキスト
public TextMeshProUGUI correctPercentageText; // 正解率のテキスト
public Image monkeyPortrait; // サルの肖像画のオブジェクト
public List<Sprite> monkeyPortraitSprite; // サルの肖像画の画像リスト
public TextMeshProUGUI resultMessage; // 結果メッセージ
// ...省略...
public void CreateResultPanel(int correctAnswerCount, int questionCount)
{
// 正解率の計算
float correctAnswerPercentage = (float)correctAnswerCount / questionCount * 100;
// 正解数の表示
correctNumberText.text = $"正解数 <size=54>{correctAnswerCount}</size>/{questionCount}問";
// 正解率の表示 (小数点以下2桁まで)
correctPercentageText.text = $"正解率 <size=54>{correctAnswerPercentage:0.##}</size> %";
// 正解率に応じてサルの肖像画とメッセージを変更
if (correctAnswerPercentage >= 80)
{
monkeyPortrait.sprite = monkeyPortraitSprite[0];
resultMessage.text = $"あなたは<size=56><color=#FDD35C>チンパンジー</color></size>です";
}
else if (correctAnswerPercentage >= 60)
{
monkeyPortrait.sprite = monkeyPortraitSprite[1];
resultMessage.text = $"あなたは<size=56><color=#FDD35C>ボノボ</color></size>です";
}
else if (correctAnswerPercentage >= 40)
{
monkeyPortrait.sprite = monkeyPortraitSprite[2];
resultMessage.text = $"あなたは<size=56><color=#FDD35C>オランウータン</color></size>です";
}
else if (correctAnswerPercentage >= 20)
{
monkeyPortrait.sprite = monkeyPortraitSprite[3];
resultMessage.text = $"あなたは<size=56><color=#FDD35C>ゴリラ</color></size>です";
}
else
{
monkeyPortrait.sprite = monkeyPortraitSprite[4];
resultMessage.text = $"あなたは<size=56><color=#FDD35C>ニホンザル</color></size>です";
}
}
}
結果画面の内容を生成する関数CreateResultPanel()
を定義しました。
19行目で正解率の計算をして、23行目で正解率の表示をしています。カスタムフォーマットを使っています。フォーマット指定子:0.##
は小数点以下2桁に丸め、小数点以下の数字が0ならば表示しないという意味です。
あと、正解率に応じてサルの肖像画とメッセージを変更しています。
QuizController.csに以下のコードを追加します。
public class QuizController : MonoBehaviour
{
// ...省略...
public ResultController resultController; // ResultController
// 終了ボタン
public void FinishGame()
{
resultController.CreateResultPanel(correctAnswerCount, currentQuestionIndex + 1); // 結果画面を生成
// ...省略...
}
// ...省略...
}
終了ボタンを押したときに、CreateResultPanel()
関数を実行して結果画面を生成します。第1引数は正解数correctAnswerCount
、第2引数は問題数currentQuestionIndex + 1
です。currentQuestionIndex
は0
から始まるので+ 1
すると出題した問題の数になります。
成績画面の表示
タイトル画面の「成績」ボタンを押したときに表示される成績画面を作ります。成績画面には累計の正解数と正解率を表示します。つまり、過去の成績データのセーブ・ロードをする必要があります。
成績データのロードと成績画面の表示
RecordController.csに以下のコードを追加します。
// ...省略...
using TMPro; // TMPを使う場合に追加
using UnityEngine.UI; // UIを使う場合に追加
public class RecordController : MonoBehaviour
{
// ...省略...
public TextMeshProUGUI correctNumberText; // 正解数のテキスト
public TextMeshProUGUI correctPercentageText; // 正解率のテキスト
public Image monkeyPortrait; // サルの肖像画のオブジェクト
public List<Sprite> monkeyPortraitSprite; // サルの肖像画の画像リスト
public TextMeshProUGUI recordMessage; // 結果メッセージ
// ...省略...
// 成績画面生成関数
public void CreateRecordPanel()
{
// データをロード
int totalCorrectAnswerCount = PlayerPrefs.GetInt("totalCorrectAnswerCount", 0);
int totalQuestionCount = PlayerPrefs.GetInt("totalQuestionCount", 0);
// 正解率の計算
float totalCorrectAnswerPercentage = totalQuestionCount == 0 ? 0 : (float)totalCorrectAnswerCount / totalQuestionCount * 100;
// 正解数と正解率の表示
correctNumberText.text = $"累計正解数 <size=54>{totalCorrectAnswerCount}</size>/{totalQuestionCount}問";
correctPercentageText.text = $"累計正解率 <size=54>{totalCorrectAnswerPercentage:0.##}</size> %";
// 正解率に応じてサルの肖像画とメッセージを変更
if (totalQuestionCount == 0) // 解答数が0のとき
{
monkeyPortrait.sprite = monkeyPortraitSprite[5];
recordMessage.text = null;
}
else
{
if (totalCorrectAnswerPercentage >= 80)
{
monkeyPortrait.sprite = monkeyPortraitSprite[0];
recordMessage.text = $"あなたは<size=56><color=#FDD35C>チンパンジー</color></size>です";
}
else if (totalCorrectAnswerPercentage >= 60)
{
monkeyPortrait.sprite = monkeyPortraitSprite[1];
recordMessage.text = $"あなたは<size=56><color=#FDD35C>ボノボ</color></size>です";
}
else if (totalCorrectAnswerPercentage >= 40)
{
monkeyPortrait.sprite = monkeyPortraitSprite[2];
recordMessage.text = $"あなたは<size=56><color=#FDD35C>オランウータン</color></size>です";
}
else if (totalCorrectAnswerPercentage >= 20)
{
monkeyPortrait.sprite = monkeyPortraitSprite[3];
recordMessage.text = $"あなたは<size=56><color=#FDD35C>ゴリラ</color></size>です";
}
else
{
monkeyPortrait.sprite = monkeyPortraitSprite[4];
recordMessage.text = $"あなたは<size=56><color=#FDD35C>ニホンザル</color></size>です";
}
}
}
}
21,22行目で、PlayerPrefsを使って累計の正解数と解答数をロードしています。第2引数が0
なので、データが存在しない場合は0
が代入されます。
24行目で正解率の計算をしています。三項演算子を使って解答数が0
なら0
を、それ以外なら計算結果を代入しています。このようにしないと、解答数が0
の場合に正解率がNaN(非数)になってしまいます。0÷0が計算できないということですね。
TitleController.csに以下のコードを追加します。
public class TitleController : MonoBehaviour
{
// ...省略...
public RecordController recordController; // RecordController
// ...省略...
// 成績ボタン
public void ShowRecord()
{
recordController.CreateRecordPanel(); // 成績画面の生成
// ...省略...
}
// ...省略...
}
「成績」ボタンが押されたときにCreateRecordPanel()
関数を実行して成績画面を生成します。
成績データのセーブ
ゲームを終了するときに成績をセーブする処理を実装します。
ResultController.csに以下のコードを追加します。
public class ResultController : MonoBehaviour
{
// ...省略...
public void CreateResultPanel(int correctAnswerCount, int questionCount)
{
// ...省略...
// 累計正解数・解答数のデータをロード
int totalCorrectAnswerCount = PlayerPrefs.GetInt("totalCorrectAnswerCount", 0);
int totalQuestionCount = PlayerPrefs.GetInt("totalQuestionCount", 0);
// 累計正解数・解答数に今回の正解数・解答数を足してデータをセーブ
PlayerPrefs.SetInt("totalCorrectAnswerCount", totalCorrectAnswerCount + correctAnswerCount);
PlayerPrefs.SetInt("totalQuestionCount", totalQuestionCount + questionCount);
}
}
10,11行目で、累計正解数・解答数のデータをロードしています。
14,15行目で、累計正解数・解答数に今回の正解数・解答数をそれぞれ足してデータをセーブしています。
さいごに
今回も、データのセーブ・ロードにPlayerPrefsを使いましたが、そろそろ卒業したいです。定番のアセットEasy Saveを使ってみたいんだけど、高いんだよなぁ。75.90ドル!今の為替レートだと壱萬圓を超えるのよ。
セールで3000円くらいにならねぇかなぁ。
でわでわ
コメント