タイピングゲーム制作記の4回目です。
前回の制作記から9カ月以上経ちました。(._.)
つい最近まで『ユニティちゃんのRPGを作ってみよう』の機能と記事を作成していた為、完全にタイピングゲームは放置しておりました・・。
時間を空けちゃだめですね、元のスクリプトをまた把握する時間が必要になりますので・・・。
ということでしばらくはタイピングゲーム制作に力を入れてジャンジャン進めちゃいます。
今回は複数の問題文が出た時にどの問題からでも入力を可能とする機能を作成しました。
複数の問題の入力を可能とする方法
まずは複数の問題が出た時にどの問題からでも入力を可能とする方法を考えました。
複数の問題から一つの問題を選択する
今までは一つの問題に対して一つのタイピングの処理をするスクリプト(TypingScriptスクリプト)を取り付けてひとつの問題だけの対処をすれば良かったんですが、複数の問題が出ている為、今どの問題の入力をしているのか?を把握する必要が出ました。
なので、キー入力がされた時にTypingScriptのUpdateメソッドでキーの判定をするのではなく、別のタイピングを管理するスクリプト(TypingManagerスクリプト)を作成し、そこでどの問題を入力しているのかを判断するようにしました。
今打つべき文字や入力済みの文字などは今まで通り個々のTypingScriptで保持していますので、今どの問題を入力しているか?をTypingManagerで管理し、今打ったキーと今打っている問題の打つべき文字が正解かどうかをその問題のTypingScriptのキー判定メソッドで判定するようにします。
ただ、どの問題も入力していない時はどの問題も入力可能なので今打ったキーが全ての問題の中から今打つべき文字と一致しているものを調べ、一致しているものがあればその問題を今入力している問題としてTypingManagerで保持します。
あとはキーボードが押された時にその問題のTypingScriptのキー判定メソッドを呼び出します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 複数の問題から最初の文字と一致している問題文を入力出来るようにする if (targetEnemy == null) { // 全ての敵の最初の文字と入力した文字の比較 foreach (var enemy in enemyList) { // 最初の文字の入力が正解だったらその敵をターゲットにする if (enemy.GetComponentInChildren<TypingScript>().KeyCheck(KeyCheckMode.CheckFirstChar, Input.inputString)) { targetEnemy = enemy; targetEnemyTypingScript = targetEnemy.GetComponentInChildren<TypingScript>(); targetEnemyTypingScript.KeyCheck(KeyCheckMode.Normal, Input.inputString); targetEnemyTypingScript.transform.Find("Background").gameObject.SetActive(true); Input.ResetInputAxes(); // 一つの敵でマッチしたら他の敵にマッチさせない為breakする break; } } |
上がその処理の一部ですが、ターゲットの敵(問題)がnullであればまだどの問題も入力していない状態なので、敵のリスト分の繰り返しを行い、その敵が持っているTypingScriptのKeyCheckメソッドで入力したキーと今打つべき文字が一致しているかを確認しています。
この際にただキーチェックをする為に調べるという列挙型を渡し、正解しているかどうかだけのbool値を得て、ここではタイピングの処理はしません。
その問題で正解していれば、その敵をターゲットにし、列挙型のKeyCheckMode.Normalを渡してその問題の実際のタイピング処理を行っています。
ターゲットを設定したらbreakで繰り返しを終了します。
今打つべき文字が同じ問題の場合はenemyListの最初の方に登録されている問題がターゲットになります。
今打っている問題をキャンセルして他の問題を打つ
問題の途中で別の問題の入力をしたくなった時はSpaceキーを押すと今の問題の入力をやめ、全ての問題の今打つべき文字の入力から出来るようにします。
今の問題をキャンセルして他の問題を打てるようにします。
現時点ではSpaceキーにしてますが、タイピングオブザデッドのようにEscキーにするかもしれません。
1 2 3 4 5 | // 敵のキャンセルに設定するキー [SerializeField] private KeyCode cancelKey = KeyCode.Space; |
確かタイピングオブザデッドの場合は今入力中の問題をキャンセルすると途中まで入力した問題を最初から入力する必要があったと思うのですが、わたくしは途中まで入力したのはそのままでキャンセルするようにしました。
なので一旦キャンセルした後にまた同じ問題のタイピングをすると途中から入力する事になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // キャンセルキーを押した時 if(Input.GetKeyDown(cancelKey)) { // ターゲットがいれば解除、いなければミスとして計算 if (targetEnemy != null) { // 間違った文字部分を消し、正解した文字列だけにする targetEnemyTypingScript.ResetToCorrectString(); // 通常の背景色にする targetEnemyTypingScript.transform.Find("Background").gameObject.SetActive(false); targetEnemy = null; } else { // ターゲットがいない時は失敗数を増やす SetMistakeNum(GetMistakeNum() + 1); } Input.ResetInputAxes(); return; } |
キャンセルキーはインスペクタでKeyCodeを選択する事で変更するようにし、いつでもキーを変更出来るようにしています。
キャンセルキーを押した時にターゲットがいた場合はターゲットを解除し、全ての問題からまた入力する問題を選択出来るようにし、ターゲットがいない場合はタイプミスとして計上しています。
問題文に合わせて背景画像とテキストのサイズを変更する
問題文の長さに合わせてテキスト群とその背景のサイズを変更しないと元のテキストが『あい』だけなのに横に長い背景を使うのは他の要素が見えなくなるので邪魔になります。
そこで、日本語表示テキスト、ローマ字表示テキスト、入力に成功したテキストの3つのテキストの一番長いテキストに合わせて背景のサイズも変更することにしました。
しかしやり方が全然わかりません。(^_^;)
しかしUnityの標準コンポーネントにContent Fitterというコンポーネントがあって、これをテキスト群全部に取りつけるとテキストの幅を文字列の幅に合わせて勝手に伸縮してくれます。
それを使って背景画像の幅も変更するようにしました。
今回の成果物
今回までの成果は以下のような感じになります。
終わりに
今回作った機能でタイピングの処理部分はほとんど出来ました。
キー入力のテスト等はまだ全然不十分ですが、これは問題文を増やしてからまた実行して細かい不具合を修正していきます。
これでやっとタイピング処理部分が終わったので後は敵と一緒にテキストを動かしたりといった普通のゲーム要素の作成に取り掛かれそうです。
テキストを敵と一緒に動かすという事は敵同士が近くにいる場合にテキストが重なって見え辛くなる問題が出てくるので、そこの対処が必要ですね。
タイピングオブザデッドのようにテキストを3D上ではなく2DのUIとして作ってさらにゲーム画面内でテキストが重ならないように動かすというのも一つのやり方ですが、
わたくしの場合は3D上のテキストとして表示し、なんとかテキストが重ならないように敵の動きを作ってみようと思います。
まぁ・・・ゲームだし重なってもいいか・・・(-_-)