【Unity(C#)】クイズゲームを作りたいんじゃ!!(後編)【SAP】

Unity

こんにちは、ばいおです。

今回は、Unityクイズゲーム作成の続きになります。
前回の記事はこちら↓よりどうぞ

また、クイズゲーム制作についての記事は↓にまとめていますので、あわせてご参照ください!

私がゲーム作成にあたり、勉強に使用したUnity本はコチラ↓
実際にサンプルゲームを作成しながら楽しく学べるので、オススメです!

Unityの教科書 Unity 2021完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)
Unity 2021に最速対応! いちばん売れているUnity入門書が最新バージョンに対応 最新環境でゲーム制作を楽しく体験しましょう! ■本書の特徴 ●初めてゲーム制作にチャレンジする人に最適! 最初は簡単な2Dゲームの制作からスタートし、徐々に難しいゲームへと進めていきます。サンプルゲームの制作を通じて、Unity...

ゲーム、完成しました!

休日を生贄にして、なんとかゲーム完成しました!
品質はさておき(問題数が少ない。。)目標達成!

Twitterにもアップしましたが、イメージはこちら↓になります。

早速unityroom(※)にアップしましたので、プレイしてもらえると嬉しいです!
(※ unityroomはUnityで作成したゲームを無料で投稿でき、投稿されたゲームをブラウザ上で遊ぶことができるサイト)

ゲームは以下リンク先よりプレイできます。是非やってみてください!(随時更新中)
https://unityroom.com/games/sapquiz

実際にゲームやってみての感想や改善点などがありましたら、ゲームリンク先のUnityroomにコメントを残せるので、是非コメントしてください!泣いて喜びます!
(ランキング機能も実装したので是非登録してくださいまし!)

まだ問題数も少なく実用的ではない&色々ショボいので、バージョンアップするつもりです。
もっとこうするといいんじゃない、とか、この問題出したほうがいい、とかありましたら是非教えて下さい!

クイズゲームの構成

最終的なゲームフローは以下のようになりました。尚、クイズは1回につき5問出題です。

タイトル ⇒ 問題 ⇒ 正誤判定 ⇒ 問題 ⇒ 正誤判定(5回目) ⇒ 最終結果 ⇒ タイトル

クイズの問題はCSVファイルから読み込むようになっております。
今回UPしたゲームの問題数は15問くらいしかありません。今後増やさなきゃですね。

しかし、私のSAPに関する知識に偏りがあるので、問題のジャンルも偏りがち。。。
現状これは仕方ないですね。もっと勉強します!

最終結果画面には、正答数に応じて出力するコメントを変えるという微妙な機能を実装しています。全体的に味気ないので、今後はもっとアクセントを加えたいところです。

クイズゲーム作成で苦戦した箇所

今回のクイズゲーム作成にあたり、私が苦戦した箇所を記載します。

このゲーム、色々なNoteやqiitaやteratailやブログを参考にすることで何とか形にできました。
先人の方々は本当に偉大だと思います。私のこの記事も、役に立つことがあれば嬉しいです。

余談ですが、SAPには疑問解決してくれる日本語プラットフォームってあるんですかね。
あれば大変助かるのですが、私が知らないだけでしょうか。
(いつも英語のサイトばかりヒットするので、苦労している。。。)

クイズ問題をCSVファイルから読み込む

このNoteが参考になりました。

Unity で CSV ファイルを読み込む方法|Flutter別荘のこんぶ
testCSV.csv というファイルを Unity で読み込むサンプルコードです。 以下,csv ファイルとスクリプトの中身です。 サンプルプロジェクトはこちら。 ダウンロードして Unity 上で実行できます。 <testCSV.csv> テーマ,需要,難易度 CSV,あんまりなさそう,簡単 ...

何故か1行目のデータだけ、うまく読み込めないという事象が発生したので、2行目から読み込むというロジック変更をしましたが、ほとんどこのNoteのロジックを適用できました。

クイズ問題をランダムに出題する

このteratailが参考になりました。

Unityクイズゲーム制作、選択肢を毎回並び替えたい
### 前提・実現したいこと 1.Unityで四択のクイズゲームを作る(7◯3✖️式を検討中) 2.問題はCSVで管理する 3.csvで取得したデータをuGUIテキスト、uGUIボタンに代入

CSVから取得した配列をシャッフルするコードは自力で思いつくのは無理だったと思います。
(↓これです)

array = array.OrderBy(x => System.Guid.NewGuid()).ToArray();

クイズ問題をかぶりなく出題する

これが一番きつかった・・・!ググっても、「これだ!」となる解決法が見つからなかったです。
なので、ここは自力で考えて作りました。

ロジックは以下です。

① CSVファイルの問題が記載されている行数を取得し、1次元配列に投入
② ①の1次元配列をシャッフル
③ ②の1次元配列を今の問題数の要素から取得
④ ③で取得した数を読み込んだCSVファイルの行数として、CSVファイルから問題を出力

読み込むCSVファイルの行数をシャッフルして、前から順番に取得していくので、この方法ならかぶりなくランダムに出題できます。
簡単なロジックですが、たどり着くのに時間がかかりました・・・。
でも、プログラムを自力で考えて書くのは楽しいですね!

苦戦した箇所のソースコード

先に挙げた苦戦した箇所3点の該当部分のソースコードを記載します。参考になれば幸いです。
ちなみに、CSVファイルの構成は、1列目が問題、2列目が答え、3〜6列目が回答候補で、問題が記載されているのは2行目からになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Linq;

public class question : MonoBehaviour
{
    TextAsset csvFile; // CSVファイル
    public static List<string[]> csvDatas = new List<string[]>(); // CSVの中身を入れるリスト;  
    public static List<int> qnumber = new List<int>(); // 出題番号リスト;     
    public int csvrow; // CSVファイルの行数
    public static string answer; // クイズの答え   
    private int k = 0; //配列の変数
    private int qransu = 0; // 出題する問題の行      

    void Start()
    {
        int qcount = gamestart.getqCount();
        if(qcount == 0) // 1問目のみ以下処理を行う
        {
            csvFile = Resources.Load("questiondata") as TextAsset; // Resouces下のCSV読み込み
            StringReader reader = new StringReader(csvFile.text); 
            while (reader.Peek() != -1) // reader.Peaekが-1になるまで
            {
                string line = reader.ReadLine(); // 一行ずつ読み込み
                csvDatas.Add(line.Split(',')); // , 区切りでリストに追加
                csvrow++; // CSVファイルの行数カウント
            }           
            for (int j = 1; j <= csvrow-1; j++) 
            {
                qnumber.Add(j); // CSVファイルの行をリストに追加(1行目は除外)
            }
            qnumber = qnumber.OrderBy ( a => System.Guid.NewGuid () ).ToList (); // 読み込んだリストをシャッフル 
            csvrow = 0; //変数初期化
        }        
        qransu = qnumber[qcount]; // シャッフルされたリストを問題数順に取得
        QuestionLabelSet();
        AnswerLabelSet();
    }

    private void QuestionLabelSet()
    {    
        csvDatas[k] = csvDatas[qransu]; // CSVの"qransu"行目の問題を取得      
        Text qLabel = GameObject.Find("Canvas/Question").GetComponent<Text> ();
        qLabel.text = csvDatas[k][0];  
    }

    private void AnswerLabelSet()
    {
        //回答文面の作成
        string[] array = new string[] { csvDatas[k][2], csvDatas[k][3], csvDatas[k][4], csvDatas[k][5] };
        array = array.OrderBy(x => System.Guid.NewGuid()).ToArray(); // 回答候補のリストをシャッフル
        //ボタンが4つあるのでそれぞれ代入
        for (int i=1; i<=4 ; i++)
        {
            Text aLabel = GameObject.Find("Canvas/Button" + i).GetComponentInChildren<Text> ();
            aLabel.text = array[i-1];
            answer = csvDatas[k][1];
        }       
    }
}

おわりに

今回は、Unityでのゲーム完成に至るまでの過程を記事にしました。

実際にゲーム作ってみて感じたのは、「ゲーム作ってる人本当すごいわ」ということですね。

こんな質素なゲームでも、開発中バグ出まくりでかなり頭を使いました。
世に出てるゲームは遥かに複雑なゲームですが、それをほぼバグなく作るって、当たり前のようでとても難しいことなんだなと再認識しました。

当たり前に動くことのありがたみってすごい。

今回出したゲーム、改善の余地しかないので、時間ある時にバージョンアップしていきます。
なにかご意見ご要望があれば、教えてくださると嬉しいです!

ここまで読んでいただきありがとうございました。

Unityの教科書 Unity 2021完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)
Unity 2021に最速対応! いちばん売れているUnity入門書が最新バージョンに対応 最新環境でゲーム制作を楽しく体験しましょう! ■本書の特徴 ●初めてゲーム制作にチャレンジする人に最適! 最初は簡単な2Dゲームの制作からスタートし、徐々に難しいゲームへと進めていきます。サンプルゲームの制作を通じて、Unity...
タイトルとURLをコピーしました