箱じゃなくてもいいんですが、脱出ゲームでよくある「箱の数字を合わせる」謎を実装する方法です。
成果物
3桁の数字を組み合わせて、正解の数字になったら別の処理を実行させる、というものを作ります。
数字合わせギミックの作り方
前準備
前準備として、こんな感じで箱を押すとウィンドウを表示、ウィンドウ右上の×を押すとウィンドウを隠す、というものを作っておきます。
ウィンドウは編集画面で最初から置いておきます。入力画面ウィンドウと×ボタンは別のオブジェクトです。
ウィンドウおよび×ボタンにスクリプトをアタッチし、StartでSetActiveをfalseに設定し、ゲーム開始時点で画面から隠します。
箱(押すとウィンドウが開く)側のスクリプトでpublic GameObjectの変数をふたつ作り、インスペクターでウィンドウと×ボタンをセットします。
箱を押したときはこのふたつのオブジェクトのSetActiveをtrue=表示にし、
×ボタンでウィンドウオブジェクト、自分自身のSetActiveをfalse=非表示に変更します。
数字をセットする
新しくUIテキストを作ります。親要素であるキャンバスのレイヤーの順序はウィンドウより前にしておきます。
テキストを設置し、比率やサイズ、位置を調節します。
フォントを変えるには、フォントファイルをアセットに追加し(otfまたはttf。手持ちがなければ、フリーフォント などで検索すると色々転がってます)。
テキストオブジェクトを選択して、フォントの部分にドラッグしてセットすればOKです。
後でイベントトリガー設置してからでもいいんですが、作ったテキストを複製して、
わかりやすく名前をつけて、
X軸の数値を変更して、みっつ横に並べておきます。
※一般公開する場合、フォントが再配布可能かどうかを規約で確認してください。
※WebGLの場合、一部のフォント(デフォルトのArialを含む)は日本語が表示できないため、文字を表示する場合フォントの変更が必須となります(数字だけならOK)。
このゲームではあずきフォントをお借りしています。
クリックすると数字が変わる(イベントトリガー)
あとはこのやりかたで、テキストにコライダーをセットしてスクリプトで数字を増やせばいい……と言いたいところですが、UIの場合コライダーを設置しても、当たり判定が発生しないようです。
当たり判定を空のオブジェクトで作ってそこにスクリプトを設置すればできるんですが、
せっかくなのでイベントトリガーを実装します。ちょっと手間ですが、UIから直接イベントを発火できる機能です。コライダーはやはり必須。
まずクリックするUIのインスペクターでコンポーネントの追加→イベント→
まずクリックするUIのインスペクターでコンポーネントの追加→イベント→
イベントトリガーをクリックします。
イベントトリガーコンポーネントが追加されたら、新しいイベントを追加→Pointer Clickをクリックします。「このオブジェクトがクリックされた」という処理になります。
+を押すとオブジェクトが「なし」となっているので、
クリックで干渉したい主なオブジェクト、「this」にしたいオブジェクトをセットしておきます。この場合自分自身です。
スクリプトを書きます。メソッド名をpublic void 好きな名前()にしておきます。
内容的にはText.textはString(文字列)なので、int型の整数に渡すために、int.Parseでテキストの「文字列」を数値に変換し、これに+1した値を、今度はToStringで「文字列」に直してテキストに表示する、というスクリプトです。
桁あふれについては、動作確認できた後で対処します。
内容的にはText.textはString(文字列)なので、int型の整数に渡すために、int.Parseでテキストの「文字列」を数値に変換し、これに+1した値を、今度はToStringで「文字列」に直してテキストに表示する、というスクリプトです。
桁あふれについては、動作確認できた後で対処します。
イベントトリガーで、No function → クラス名 → メソッド名と指定します。
これでイベントトリガーはセットできましたが、イベントトリガーを使う場合は他にもう少しやることがあります。
もしこの時点でなければ、ヒエラルキーの+(Create)→UI→Event Systemを追加します。
さらにMain Cameraオブジェクトを選択し、
Main Cameraのインスペクターでコンポーネントの追加をクリックし、イベント→
2D物理レイキャスターをクリックします。これで完成。
実行するとちゃんと反応しますが、表示こそされないものの、数字が二けた以上まで増やせる問題と、
数字がウィンドウと連動していない問題が起きています。
前者の問題は数字が10になったら-10するIf文で処理、
後者の問題はSetActiveをウィンドウと同じ要領でtrue/false切り替えることで対処できます。
だいぶそれっぽくなってきました。が、まだ問題があります。
画面を切り替えても数字を保持
細かい点ですが、画面(シーン)を切り替えるとセットした値がリセットされる、というのも気になるところです。
Static(シーンを切り替えても保持される)の整数をみっつと、meという変数を作り、
数字の左、中央、右それぞれの「Me」に1から3まで数字をインスペクターでセットします。
クリックした後、Meの値(=どの数値か)によって処理をSwitchで振り分け、Staticの値に別々に現在の数値を保存します。
シーンが変わる時(Startメソッドなど)にStaticの値からTextの値に代入するようにしてやれば、
戻ってきても数字がそのまま保持されます。
正解時の処理
最後に正解した時の処理の実装ですが、仮に正解が「123」だとして、
さっきのみっつの変数を使い、複数条件のIf文で指定すればOKです。if(条件A && 条件B)のようにしてやれば、複数条件でIf文が作れます。
実行結果です。実際はフラグ立てて、正解後はこの数字合わせができないようにしたいところですが、どうなったかは完成品を見てもらえればと思います。
//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の時期に書き始めているので、それより前のバージョンについては言及しません。
コメント