Unityで作る4択クイズpart2

part1 ↓↓↓

参考

https://engineer.blog.lancers.jp/2015/05/ugui_quiz_unity/

part2

次に核の部分である、クイズ部分を作っていきます。(^o^)丿

asset内でCreate→C#scriptから、Questionを作成します。

そして、canvas(写真では名前を変えてQuiz)にドロップします。

↓↓以下スクリプト↓↓

using UnityEngine;
using System.Collections;
using UnityEngine.UI;//UI オブジェクトを扱う時は必須
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Random = UnityEngine.Random;


public class Question : MonoBehaviour {

    public string[] questions = {
        "シェル変数の一覧を実行するにはどのコマンドラインを実行すればよいか",
        "変数TESTをシェルの子プロセスも参照できるようにするコマンドはどれですか?",
        "cd ~yuko を実行したときの適切なものはどれか",
        "date +%M コマンドを実行した際、適切なものはどれか",
        "manコマンドが実行時に参照するドキュメントファイルのおかれている場所は",
        "履歴番号が100のコマンド履歴を消去するために入れるオプションを一文字選べ",
        "yukoとしてログインしている状態から、現在のシェルを終了させることなくroot権限と環境でログインしなおすのは",
        "dir_b/subdirをユーザーyukoのホームディレクトリの下に作るのに適したものを選べ",
        "ファイルの属性を表示するために、適切なものはどれか",
        "",

        };
    public int num;
    public string nQJ;
    public static  string answer;
    

 
     //アタッチしたオブジェクトが呼ばれた時に実行される。
    void Start () {
        num = Random.Range(0,questions.Length);
        nQJ = questions[num];
        QuestionLabelSet ();
        AnswerLabelSet();
    }
 
    private void QuestionLabelSet(){

        //特定の名前のオブジェクトを検索してアクセス
        Text qLabel = GameObject.Find("Quiz/QuestionField").GetComponentInChildren<Text> ();
        //データをセットすることで、既存情報を上書きできる
        qLabel.text = nQJ;
    }
    private void  AnswerLabelSet(){
        //回答文面の作成
        string[][] array = new string[questions.Length][];
        //正解の選択肢は必ず一番前に持ってきます。
        //下のアンサーで使います。
        array[0] = new string[4]{"set","env","env -a","set -a"};
        array[1] = new string[4]{"declear x TEST","set TEST","export -v TEST","declear TEST"};
        array[2] = new string[4]{"ユーザーyukoのホームディレクトリに移動","文法エラー","/~yukoというディレクトリがあればそこに移動","実行ユーザのホームディレクトリの下のyukoディレクトリに移動"};
        array[3] = new string[4]{"日時の分のみが表示される","日時の月のみが表示される","日時の時のみが表示される","日時の日のみが表示される"};
        array[4] = new string[4]{"/usr/share/man","/usr/share/manual","usr/local/manual","usr/local/share"};
        array[5] = new string[4]{"$history -d 100","$history -c 100","$history -!! 100","$history -↓ 100"};
        array[6] = new string[4]{"su -root","change --login root","su root","su /root/.bashrc"};
        array[7] = new string[4]{"mkdir -p /home/yuko/dir_b/subdir","mkdir /home/yuko/dir_b/subdir","mkdir -P /home/yuko/dir_b/subdir","mkdir -r /home/yuklo/dir_b/subdir"};
        array[8] = new string[4]{"lsatter filename","ls --attr filename","file --attr filename","attr filename"};
        array[9] = new string[4]{"僕がやります","頑張れ","青眼の白龍","グレムリン"};    

        answer = array[num][0];
        array[num].Shuffle();


        //ボタンが4つあるのでそれぞれ代入
        for (int i=1; i<=4 ; i++){

            Text ansLabel = GameObject.Find("Quiz/AnsButton" + i).GetComponentInChildren<Text> ();
            ansLabel.text = array[num][i-1];
        }
    }
    public static string get()
    {
        return answer;
    }

}


public static class Extensions  //拡張メソッド用 static クラス(名前は任意)
{
    //配列の要素をシャッフルする (Fisher-Yates shuffle)
    public static void Shuffle<T>(this T[] arr)
    {
        for (int i = arr.Length - 1; i > 0; i--)
        {
            int j = Random.Range(0, i + 1);  //[0]~[i]
            T tmp = arr[i];     //swap
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }
}

詳しい説明を

↓↓問題文を用意します。questionsのリストの中身が該当箇所です。

今回は、問題文は省略して一つにしています。

public string[] questions = {
"シェル変数の一覧を実行するにはどのコマンドラインを実行すればよいか",
    };

自分が作った時点では問題数がそんなに多くなかったのでコードにべた書きですが、管理のしやすさと見た目の問題を考えると、外部ファイルからの読み込みにしたほうが良いのかもしれないです。

start関数内の説明。

一行目で上のリストの長さからランダムな数字を選ぶ。

二行目でquestionsのリスト内から選ばれら数字の問題を選んでいく。

三四行目は下でつくります。

void Start () {
    num = Random.Range(0,questions.Length);
    nQJ = questions[num];
    QuestionLabelSet ();
    AnswerLabelSet();
}

問題を設定する。

問題表示用のテキスト設定をいじっていきます。

上で選ばれた問題文をテキストに代入しています。

private void QuestionLabelSet(){

    Text qLabel = GameObject.Find("Quiz/QuestionField").GetComponentInChildren<Text> ();
    //データをセットすることで、既存情報を上書きできる
    qLabel.text = nQJ;
}

array内に選択肢を設定して、for文を使ってそれぞれ当てはめていく。

答えの選択肢は配列の一番前[0]番目に持ってくる必要があります。

選択肢のシャッフルを行う必要が出てきます。

array[num].Shuffle();

ここに関しては下で説明します。

private void  AnswerLabelSet(){
    //回答文面の作成
    string[][] array = new string[questions.Length][];
  //正解の選択肢は一番前に持ってくる
    array[0] = new string[4]{"set","env","env -a","set -a"};

    answer = array[num][0];
    array[num].Shuffle();


    //ボタンが4つあるのでそれぞれ代入
    for (int i=1; i<=4 ; i++){

        Text ansLabel = GameObject.Find("Quiz/AnsButton" + i).GetComponentInChildren<Text> ();
        ansLabel.text = array[num][i-1];
    }
}

パート1で作った正誤判断するスクリプトに答えを渡す。

    public static string get()
    {
        return answer;
    }

問題をシャッフルするための拡張メソッド↓↓

AnswerLabelSet内で使用しています。

これを使って、array内の選択肢をシャッフルしています。

もしこれを行わないと、必ず一番上の選択肢が答えになってしまいます。(笑)。

public static class Extensions  //拡張メソッド用 static クラス(名前は任意)
{
    //配列の要素をシャッフルする (Fisher-Yates shuffle)
    public static void Shuffle<T>(this T[] arr)
    {
        for (int i = arr.Length - 1; i > 0; i--)
        {
            int j = Random.Range(0, i + 1);  //[0]~[i]
            T tmp = arr[i];     //swap
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }
}


以上で問題の設定と選択肢の設定が終わります。

前回のものと合わせて、クイズゲーム内の処理はすべて終わりました。

あとは、resultシーンとresult_falseのシーンを作って、プレイヤー行動に応じて画面を遷移していきます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です