Unityで連続、複数のQTEに対応する

今回は1つのQTE(QuickTimeEvent)が終わったら連続して次のQTEが出現する機能、

また同時に複数のQTEを出現させ順番に実行させる機能を作成していきます。

今回の機能は

UnityでQTE(QuickTimeEvent)機能を作成する
Unityでアクションゲーム等で登場するQTE(QuickTimeEvent)機能を作成していきます。

の記事で作成した1つのQTE機能を改造して対応していくので、まだ見ていない方は↑の記事を参照してください。

スポンサーリンク

QTEクラスを作成し情報をまとめる

1つのQTEを実行する時はあまり気にしなくてもよかったんですが、連続したり複数を同時に表示する場合は『押すべきボタン』『制限時間』等、

QTEの情報がばらばらにあると不便です。

そこで1つのQTEの情報をクラスという形でまとめてしまい使いやすくします。

新しいスクリプトQTEClassスクリプトを作成します。

クラスに情報をまとめたのでインスペクタで設定する際も1つ1つのQTE情報を指定する事が出来ます。

C#で作成した場合は

Systemをディレクティブで宣言し、クラス宣言の前に[Serializable]というアトリビュート(属性)を付けておきます。

そうしないとインスペクタで値を設定する事が出来ません。

placeはQTEを表示する場所をゲームオブジェクトを指定して設定出来るようにします。

この情報を使う事でこのゲームオブジェクトが動けばQTEも一緒に動くようになります。

QTEUIを変更する

QTEを連続、複数登場させることにより押すべきボタンのテキストなど幅を取り過ぎて邪魔になるので、

QTEUIをもっとシンプルに表示出来るようにします。

シンプルにしたQTEUI

↑のようにQTEUIの子要素にあったTextを削除し、SliderをImageの上に移動します。

SliderがImageの背景に表示されるように位置を調整し、PanelのアンカーをMiddle Centerに変更し、Width、Heightを40ほどにします。

QTEUIのサンプル画像

↑が作成したものでImageの周りをSliderのイメージが取り囲むという感じになりました。

QTEを連続で表示

まずはQTEを1回のイベントで連続して表示するように改造します。

主人公操作スクリプトQTECharacterMoveを改造

主人公操作スクリプトを改造します。

MyStateQTEの後に2と書いてありますが、これはわたくしの都合上なっているだけなので2を消してください。

ほぼ同じなので一部抜粋します。

QTE状態の時の処理でQTEが終了しているかどうかを確認し、終了していたら自身の状態を変更するようにします。

主人公の検知とQTEのパラメータ設定スクリプトSearchCharaAndParamを改造

主人公の検知とQTEパラメータの設定をしていたSearchCharaAndParamスクリプトを改造します。

わたくしの都合上スクリプト名はSearchCharaAndParam2となっていますが、名前は変更せず改造してください。

またPushButtonやMyStateQTEなどenumで宣言したものも番号が振られていたりしますが、都度読み替えてください。

limitやpushButtonの変数を宣言しそこにQTEの情報を入れていましたがQTEClassにまとめたのでそれらの変数を削除し他の関数を呼び出す時にQTEClassごと渡すようにします。

QTEClassは配列にしてインスペクタで複数設定出来るようにしたのでnum変数を使って順番にQTEの情報を取りだすようにしています。

SetFinishでは連続したQTEに対応する為、設定したQTEの数を越えるまではfinishにtrueを入れません。

次のQTEクラスを指すようにし再度SetParam関数を呼び出しています。

TimeLimitスクリプトを改造

次にTimeLimitスクリプトを改造していきます。

わたくしの都合上TimeLimit2という名前になっていますが、そのままTimeLimitスクリプトを改造してください。

スクリプト中に2と記述されてるところは削除する必要があります。

QTEの押すべきボタンをSprite配列として持っておき押すべきボタンに合わせて画像を変えるようにします。

↑のあたりが追加した変数ですね、QTEを指定されたゲームオブジェクトの場所に表示し一緒に動かすので動かすパネルのRectTransform情報を使います。

SetParam関数では連続したQTEイベントに対応する為、タイマーイメージの色やスライダーの値を初期値に戻しています。

また
this.place = qte.GetPlace();
// 指定したゲームオブジェクトの位置をスクリーン位置にし移動させる
panel.position = Camera.main.WorldToScreenPoint(place.position);

の部分でQTEのパネルを指定したゲームオブジェクトの位置に表示します。

QTEのパネルはUIなので3D空間にあるplaceの場所をUIの位置に調整してから位置を設定しています。

それをしているのが

Camera.main.WorldToScreenPoint(place.position)

ですね。

メインカメラから指定する3D空間の位置(place.position)のスクリーン位置(カメラの描画範囲の位置)を取得出来ます。

この処理はUpdate関数内でも記述し、ゲームオブジェクトと一緒に動くようにしています。

これでスクリプトの改造が出来ました。

連続したQTEが実行出来るか確認

機能の改造が出来たのでインスペクタで設定し実行してみましょう。

SearchCharaAndParam2インスペクタの設定

QTESearchAreaに設定しているSearchCharaAndParam2のインスペクタで1つ1つのQTEの設定をします。

QTEを表示する位置のゲームオブジェクトCubeを作成し、移動させるようにしておきます。

TimeLimit2にImageを設定

Sliderに設定しているTimeLimit2スクリプトではボタンに対応するSpriteを設定します。

連続QTEサンプル

↑のように最初のQTEが主人公キャラの位置に表示され、それを成功するとCubeの位置に次のQTEが表示されました。

QTEを複数表示する

QTEを連続で表示する事は出来ましたが、あらかじめ複数のQTEを表示しておき次に押すべきボタンがわかるようにしたい事もあります。

そこでさらにさきほど作った機能を改造し複数のQTEを表示したり、同時にタイマーが起動するか順番にタイマーを起動するかを選択出来たりする機能を取りつけます。

QTEUIに複数のQTEを設置する

まずは同時に表示するQTEのUIを作成します。

複数のQTEUIを設置

特に新しいUIを作成するのではなくPanelをコピーして名前をPanel1、Panel2、Panel3と変更しておきます。

主人公の検知とQTEのパラメータ設定スクリプトSearchCharaAndParamを改造

次にキャラクター検知とQTEの情報を設定するSearchCharaAndParamスクリプトを改造します。

mode変数を用意し、trueであればタイマーを順番に起動しfalseであれば設置したQTEのタイマーが同時に起動するようにします。

今まではTimeLimitは1つだけでしたが、今回の場合それぞれのQTEでタイマーを管理する必要があるのでQTE数分のTimeLimitスクリプト配列を用意し、

それぞれに設定が出来るようにしてます。

それぞれのQTEパネルの親要素はQTEUIゲームオブジェクトなのでその子要素の数分の配列を確保するということになります。

TimeLimitスクリプトのSetParam関数にboolean型の新しい引数を定義しそこでタイマーがスタートするかどうかのフラグを渡すようにします。

タイマーを順番に起動するモードになっている場合は最初のひとつ以外はタイマーをスタートさせません。

TimeLimitスクリプトの改造

QTEのタイマーがスタートするかどうかの設定箇所やタイマーが起動しているQTEUIの拡大をしたりする処理を追加します。

amplificationでタイマーが起動しているQTEの拡大率を指定します。

Update関数内でQTEUIを指定したゲームオブジェクトの位置に表示してましたが、タイマーがスタートしていないQTEも動かすようにしたいので、

startTimerの条件の外に配置するようにしました。

SetParam関数では引数にboolean型のものを追加しそのフラグによってタイマーを起動したりQTEのUIを拡大したりといった事を行っています。

今回の場合、複数のQTEを表示していますが実行出来るのはインスペクタで設定した順番になります。

同時にタイマーを起動する設定にして実行するとQTEのUIが拡大し全てのQTEが実行出来そうですが出来ません。

ここら辺はSearchCharaAndParamスクリプト内でTimeLimitスクリプトを呼び出す時に拡大率を渡すような処理をすると出来そうな気もします。

また、複数のQTEが表示されることによってQTEを失敗した時に他のQTEのUIが残ってしまう状態になるので、

QTEが実行出来なかった時に実行していたSetFinish関数でその時の処理をするのではなくSetDead関数を作りQTEUIゲームオブジェクトごと非アクティブにする処理を追加し、

それを呼び出すように変更しました。

複数のQTEを表示する機能を確認

複数のQTEを表示するように改造出来たので確認してみましょう。

複数のQTEに対応した設定

QTESearchAreaに設定したSearchCharaAndParamスクリプトのインスペクタに設定をします。

次にPanel1~Panel3の子要素のSliderに設定しているTimeLimitスクリプトの設定をします。

インスペクタで拡大率を設定

↑のように拡大率を2に設定しました。

それではModeのチェックを入れた状態(タイマーを順番に起動)と外した状態(タイマーを同時に起動)の両方を確認してみます。

まずはModeにチェックを入れて確認します。

↑のように順番にタイマーが起動され、今現在のQTEだけ少し大きくなっています。

次はModeのチェックを外して確認します。

↑のように同時にタイマーが起動され、全てのQTEが少し大きくなっていますが、押さなければいけないのは主人公の所に表示されているQTEです。

この今押すべきQTEの表示をもっとわかりやすく改造すると良さそうですね。

良さそうというだけで作りませんが・・・・・(;一_一)

複数のQTE対応機能を作り終えて

今回複数のQTEに対応しましたが、元々1つのQTE機能を使い勝手をそのままに改造したので中身はゴチャゴチャした感じになりましたね。

今回の場合は主人公キャラクターがずっと止まった状態なので、QTE時には自動で動くようにして次々とQTEが発生するというものもがんばれば作れると思います。

QTEの発生場所もゲームオブジェクトの位置に発生させる事ができるので、今回のように見えるゲームオブジェクトだけでなく見えないゲームオブジェクトを設置しそこに

QTEを表示させるという事も出来ます。

今回のQTE用の画像が押すべきボタンと一致していないのはご愛敬ということで・・・・(-_-)

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます