Unityで箱の数字を合わせると箱が開くギミックの作り方/イベントトリガーの使い方

IT

箱じゃなくてもいいんですが、脱出ゲームでよくある「箱の数字を合わせる」謎を実装する方法です。

スポンサーリンク

成果物

hako5
3桁の数字を組み合わせて、正解の数字になったら別の処理を実行させる、というものを作ります。

数字合わせギミックの作り方

前準備

hako1
前準備として、こんな感じで箱を押すとウィンドウを表示、ウィンドウ右上の×を押すとウィンドウを隠す、というものを作っておきます。
numberbox1
ウィンドウは編集画面で最初から置いておきます。入力画面ウィンドウと×ボタンは別のオブジェクトです。
numberbox2
ウィンドウおよび×ボタンにスクリプトをアタッチし、StartでSetActiveをfalseに設定し、ゲーム開始時点で画面から隠します。
numberbox3
箱(押すとウィンドウが開く)側のスクリプトでpublic GameObjectの変数をふたつ作り、インスペクターでウィンドウと×ボタンをセットします。
numberbox4
箱を押したときはこのふたつのオブジェクトのSetActiveをtrue=表示にし、
numberbox5
×ボタンでウィンドウオブジェクト、自分自身のSetActiveをfalse=非表示に変更します。

数字をセットする

numberbox6
新しくUIテキストを作ります。親要素であるキャンバスのレイヤーの順序はウィンドウより前にしておきます。
numberbox7
テキストを設置し、比率やサイズ、位置を調節します。
numberbox8
フォントを変えるには、フォントファイルをアセットに追加し(otfまたはttf。手持ちがなければ、フリーフォント などで検索すると色々転がってます)。
numberbox9
テキストオブジェクトを選択して、フォントの部分にドラッグしてセットすればOKです。
numberbox10
後でイベントトリガー設置してからでもいいんですが、作ったテキストを複製して、
numberbox11
わかりやすく名前をつけて、
numberbox12
X軸の数値を変更して、みっつ横に並べておきます。

※一般公開する場合、フォントが再配布可能かどうかを規約で確認してください。
※WebGLの場合、一部のフォント(デフォルトのArialを含む)は日本語が表示できないため、文字を表示する場合フォントの変更が必須となります(数字だけならOK)。
このゲームではあずきフォントをお借りしています。

クリックすると数字が変わる(イベントトリガー)

numberbox14
あとはこのやりかたで、テキストにコライダーをセットしてスクリプトで数字を増やせばいい……と言いたいところですが、UIの場合コライダーを設置しても、当たり判定が発生しないようです。
numberbox15
せっかくなのでイベントトリガーを実装します。ちょっと手間ですが、UIから直接イベントを発火できる機能です。コライダーはやはり必須。
まずクリックするUIのインスペクターでコンポーネントの追加イベント
numberbox16
イベントトリガーをクリックします。
numberbox17
イベントトリガーコンポーネントが追加されたら、新しいイベントを追加Pointer Clickをクリックします。「このオブジェクトがクリックされた」という処理になります。
numberbox18
を押すとオブジェクトが「なし」となっているので、
numberbox19
クリックで干渉したい主なオブジェクト、「this」にしたいオブジェクトをセットしておきます。この場合自分自身です。
numberbox20
スクリプトを書きます。メソッド名をpublic void 好きな名前()にしておきます。
内容的にはText.textはString(文字列)なので、int型の整数に渡すために、int.Parseでテキストの「文字列」を数値に変換し、これに+1した値を、今度はToStringで「文字列」に直してテキストに表示する、というスクリプトです。
桁あふれについては、動作確認できた後で対処します。
numberbox21
イベントトリガーで、No function → クラス名 → メソッド名と指定します。
numberbox22
これでイベントトリガーはセットできましたが、イベントトリガーを使う場合は他にもう少しやることがあります。
onclk16
もしこの時点でなければ、ヒエラルキーの+(Create)UIEvent Systemを追加します。
onclk17
さらにMain Cameraオブジェクトを選択し、
onclk18
Main Cameraのインスペクターでコンポーネントの追加をクリックし、イベント
onclk19
2D物理レイキャスタークリックします。これで完成。
hako4
実行するとちゃんと反応しますが、表示こそされないものの、数字が二けた以上まで増やせる問題と、
hako3
数字がウィンドウと連動していない問題が起きています。
numberbox23
前者の問題は数字が10になったら-10するIf文で処理、
numberbox24
後者の問題はSetActiveをウィンドウと同じ要領でtrue/false切り替えることで対処できます。
hako5
だいぶそれっぽくなってきました。が、まだ問題があります。

画面を切り替えても数字を保持

hako6
細かい点ですが、画面(シーン)を切り替えるとセットした値がリセットされる、というのも気になるところです。
numberbox26
Static(シーンを切り替えても保持される)の整数をみっつと、meという変数を作り、
numberbox27
数字の左、中央、右それぞれの「Me」に1から3まで数字をインスペクターでセットします。
numberbox28
クリックした後、Meの値(=どの数値か)によって処理をSwitchで振り分け、Staticの値に別々に現在の数値を保存します。
s2
シーンが変わる時(Startメソッドなど)にStaticの値からTextの値に代入するようにしてやれば、
hako7
戻ってきても数字がそのまま保持されます。

正解時の処理

numberbox25
最後に正解した時の処理の実装ですが、仮に正解が「123」だとして、
numberbox30
さっきのみっつの変数を使い、複数条件のIf文で指定すればOKです。if(条件A && 条件B)のようにしてやれば、複数条件でIf文が作れます。
hako8
実行結果です。実際はフラグ立てて、正解後はこの数字合わせができないようにしたいところですが、どうなったかは完成品を見てもらえればと思います。
//Unity C#
using UnityEngine.UI;

//数字みっつにこのスクリプトを使用
public class numbers : MonoBehaviour
{
    public int get_number;
    public static int hako_l;
    public static int hako_m;
    public static int hako_r;
    public int me;
    public Text text;

    // Start is called before the first frame update
    void Start()
    {
      Staticの値をTextに代入
        switch (me)
        {
            case 1:
                this.GetComponent<Text>().text = hako_l.ToString();
                break;
            case 2:
                this.GetComponent<Text>().text = hako_m.ToString();
                break;
            case 3:
                this.GetComponent<Text>().text = hako_r.ToString();
                break;
        }
        this.gameObject.SetActive(false);
    }

    public void clk()
    {
      数字を増やし、10になったら0に戻す
        get_number = int.Parse(this.GetComponent<Text>().text) + 1;
        if(get_number >= 10)
        {
            get_number += -10;
        }
        this.GetComponent<Text>().text = get_number.ToString();

      Staticの値に現在の値を代入
        switch (me)
        {
            case 1:
                hako_l = get_number;
                break;
            case 2:
                hako_m = get_number;
                break;
            case 3:
                hako_r = get_number;
                break;
        }

      正解
        if(hako_l == 1 && hako_m == 2 && hako_r == 3)
        {
            text.text = "箱の中には……";
        }

    }
}
やりたいことから逆引きするUNITYの使い方まとめ
Unityをやりたいことから学習していけるよう、機能・用途別にまとめたページです。C#の命令別の逆引きは現時点で作っていません。2019の時期に書き始めているので、それより前のバージョンについては言及しません。

コメント