UnityでQTE(QuickTimeEvent)機能を作成する

UnityのアクションゲームにQTE(QuickTimeEvent)機能を取り付けたいと思います。

QTEとはアクションゲーム等で突如として現れる制限時間内にボタンを押さないと失敗とされてしまうイベントですね。

今回はQTEを簡単に複数個の設置が出来るようにし、設置したい場所に置いてインスペクタでパラメータ調整するようにします。

作成する段階ではゲームオブジェクトの連携でわかり辛い感じですが、一旦作ってしまえば設置する時に楽になります。

まぁ・・・連携がわかり辛くなってるのはわたくしの能力不足でそうなっているだけだと思うので、ご自分のわかりやすいよう修正してください。(^_^;)

スポンサーリンク

QTEプレハブを作成

QTEプレハブはQTEに関するゲームオブジェクトをひとつにまとめたものでQTEを発生する場所に設置してパラメータ調整するだけでいいようにします。

まずはヒエラルキー上で右クリック→Create Emptyを選択し名前をQTEとします。

QTEをデフォルトの位置に置く

キャラクターを検知するエリアの作成

QTEの子要素に右クリック→3D Object→Cubeを選択し名前をQTESearchAreaとします。

QTEのキャラサーチエリア

Box ColliderのIs Triggerにチェックを入れ物理的に当たらないようにします。

Assetsフォルダで右クリック→Create→Materialを選択しMaterialの色や透明度を変更し、QTESearchAreaにドラッグ&ドロップし設定します。

このマテリアルはサンプルの為にキャラクターがQTEエリアに侵入したのがわかりやすくなるよう設定しただけで、本来であればキャラクターをサーチする為だけのエリアなので、

マテリアルを設定して色を付ける必要はありません(ゲームに使う時はQTESearchAreaは透明のはず)。

SearchCharaAndParamスクリプトは後で作成しますが、PushButtonはInputManagerで設定しているボタンの選択、Limitはボタンを押さなければいけない時間の設定になります。

QTEのキャラサーチエリア実物

作成したQTESearchAreaは↑のようになります。

このエリアにキャラクターが侵入するとQTEが発生し、設定したPushButtonに対応するボタンを押さなければいけません。

キャラの検知とQTEの設定をするSearchCharaAndParamスクリプトの作成

さきほど作成したQTESearchAreaにキャラクターを検知する処理とQTEの設定の処理をするSearchCharaAndParamスクリプトを作成しましょう。

PushButtonをenumで宣言し、InputManagerで設定したボタンを並べます。

QTEのボタン押しの処理(キャラクター操作スクリプト内で記述する予定)でキーボードのキーやゲームパッドのボタンを個別に選択(SPACEキーを押したら等)出来るようにしてもいいのですが、InputManagerで指定したボタンを使う事で、

キーボードやマウス、ゲームパッド、どれでも操作出来るようにしています。

QTEはUIを使ってボタンを押すまでの時間を表示します。

TimeLimitスクリプトはタイマーを進めるスクリプトで後で作成します。

QTEUI、TimeLimit共に自身の階層から取得するようにしていますが、public変数を使ってインスペクタで設定しても大丈夫だと思います。

QTE用のUIはイベントが発生するまでは表示したくないのでStart関数内で非表示にしています。

OnTriggerEnter関数でキャラクターがQTESearchArea内に侵入したかどうかを判定し、キャラクターに設定しているスクリプトQTECharacterMoveの取得と

TimeLimitスクリプトへのパラメータの渡しとキャラクターの状態の変更をしています。

SetFinish関数はQTEが終わった時に呼び出す関数で、finish変数をtrueにしQTE用のUIを非表示にしています。

GetPushButton関数はこのQTEで押すべきボタンを返す関数でキャラクター操作スクリプトQTECharacterMoveスクリプトから呼び出して使います。

QTE表示用UIの作成

次にキャラクターがQTESearchAreaに侵入した時に表示するUIを作成していきます。

QTEの子要素に右クリック→UI→Canvasを選択し、名前をQTEUIとします。

QTEUIの子要素に右クリック→UI→Panelを選択します。

Panelの子要素に右クリック→UI→Imageを作成します。

QTE用下向き矢印

これはボタンを押す事を促す為のイメージなので、Source Imageに方向のイメージを指定します。

下向きにする為RotationのZに-180を設定し回転させています。

右クリック→UI→Textを作成します。

QTE用テキスト

テキストは押すべきボタンを表示する場所でデフォルトで『Push Space Key』という文字を設定しておきます。

テキストはスクリプトから変更するので初期値を指定しなくても大丈夫です。

右クリック→UI→Sliderを作成します。

QTE用TimeLimitスクリプト

SliderにはTimeLimitスクリプトを作成し取りつけます。

中身は後で作成しますが、TimerImageは時間がなくなった時に色を変更するイメージを指定し、LimitPerは何パーセントを超えたら色を変更するか、

Textは押すべきボタンを表示する為のTextを指定します。

QTE用タイマーイメージ

Sliderの子要素にFillがありますが、これをQTEの時間経過を知らせるイメージとして使用します。

Source Imageにはストップウォッチのイメージを指定し、Image TypeをFilledにし、Fill MethodをRadial 360に変更します。

Radial 360にする事で車の速度メーターのような値を表現する事が出来るようになります。

Sliderの値が0~100で変化していく事で1周グルッとイメージが表示される感じになります。

QTE用UIの全体イメージ

↑が作成したQTE用のUIです。

QTEタイマー処理をするTimeLimitスクリプトの作成

QTEのタイマー処理をするTimeLimitスクリプトを作成していきます。

Update関数内で時間が制限時間を超えていない時で、limitPerの時間を超えたら指定したイメージの色を変更しています。

制限時間を超えたらQTEを終了し、キャラクターの状態を変更します。

SetParam関数では受け取ったQTECharacterMoveスクリプト、押すべきボタン(PushButton)、制限時間(limit)をTimeLimitスクリプトで管理する為に

変数に代入してます。

受け取ったpushButtonによって表示するテキストを変更し、SetStartTimer関数にtrueを渡して呼び出しタイマーをスタートさせています。

表示するテキストはSPACEやMouseといった限定した言葉になっていますが、例えばPS3用のコントローラー限定の操作だとしたら、

×ボタンを押せとか○ボタンを押せとかに変更するといいと思います。

InputManagerで設定したボタンで判断しているのはキーボードやマウス、ゲームパッドどれで操作してもスクリプトの処理を変えない為で、

表示するテキストの言葉だけ変えればいいようにしています。

また、テキストを表示するのではなく押すべきボタンのイメージを変更して表示するだけの方が視覚的にわかりやすくなります。

例えばゲームパッドの×ボタンを押さなければならないのであれば下向きのイメージ(今回の場合方向イメージにした部分)を×ボタンのイメージの表記に変えればわかりやすくなります。

Start関数内で初期化処理をしていましたが、Start関数が実行される前にSetParamが呼ばれる事があるのでSetParam内で初期化処理をするように書き換えました。(2017/03/05)

QTEUIにアニメーションをさせる

さきほど作成したQTE用のUI群であるQTEUIですが、これをそのまま表示するだけでは味気ないのでアニメーションを作成しボタンを押す事を促しましょう。

Panelを選択しアニメーションを作成

QTEUIの子要素のPanelを選択します。

UIのアニメーションを作成

UnityのメニューからWindow→Animationを選択し、Animationタブを表示します。

AnimationタブのCreateボタンを押します。

PushAnimationという名前で保存

新しいダイアログが表示されるので、名前を付けて保存します。

PushAnimationファイルが作成される

QTEUIのアニメーターコントローラー

AnimationタブのCreateボタンを押すとアニメーターコントローラーとアニメーションファイルが作成されるので確認しましょう。

QTEUIアニメーターをAnimatorタブで見るとEntryからPushAnimation状態へと遷移するように作られています。

PushAnimation状態にはPushAnimationアニメーションが設定されておりキャラクターのアニメーターコントローラーと同じように作られている事がわかります。

またQTEUIオブジェクトにはAnimatorコンポーネントが設定されControllerにはQTEUIアニメーターコントローラーが設定されます。

フレームの中間でUIを動かす

Animationタブで録画ボタン(赤い丸印)が押されているのを確認したらフレームの0:15部分を選択します。

Panelを選択して動かす

Panelを選択した状態でSceneタブを表示し少し下に動かします。

サンプルではY軸で下に10ほど移動させています。

フレームの最初と中間にキーフレームが作成される

録画ボタンが押されていると最初のフレーム(0:00)と現在のフレーム(0:15)にキーフレームが自動で打たれます。

初期フレームをコピー

最初のフレームを選択しCtrl+Cキーを押してコピーし、0:30フレームを選択した後にCtrl+Vキーを押してペーストします。

これで0:15フレームではPanelが少し下に移動し、0:30フレームで元の場所に戻るというアニメーションが作成されました。

QTEゲームオブジェクトをプレハブ化する

QTEゲームオブジェクトが完成したのでこれをプレハブ化して量産出来るようにしましょう。

QTEゲームオブジェクトを選択し、それをAssetsフォルダにドラッグ&ドロップします。

QTEをプレハブ化する

これでQTEがプレハブになります。

QTEイベントを設置したい時にはAssetsフォルダにあるQTEをヒエラルキーにドラッグ&ドロップして設置したい位置に移動させ、SearchCharaAndParamの設定値を変更します。

キャラクター操作スクリプトQTECharacterMoveスクリプトの作成

今回使用するキャラクター操作スクリプトを作成しましょう。

今回のサンプル用の操作スクリプトなので、既にキャラクター操作スクリプトを作成している場合は処理を追加する形で作成してください。

キャラクターが外部スクリプトからMyStateQTE.QTEの状態へと変更された場合は、Update関数内でQTE用の処理をしています。

searchCharaAndParamスクリプトのGetPushButton関数を呼び出して、押すべきボタンを取得してます。

ただGetPushButton関数で戻ってくる値はPushButton型の値なのでToString関数を使用して文字列へと変換してInput.GetButtonDownの引数として指定してます。

主人公キャラが死亡となった場合は自身のアニメーションパラメータのDeadトリガーを作用させアニメーションを変更しています。

主人公キャラのアニメーターコントローラー

主人公のアニメーターコントローラーにはDeadというTrigger型のアニメーションパラメータを作成し、

↑のようにAny StateからDeadへの遷移を作成しDeadがトリガーされたら遷移するように作成します。

QTEを確認する

QTEプレハブが出来たので設置して確認してみましょう。

QTEを配置

QTEプレハブをヒエラルキー上にドラッグ&ドロップして設置します。

QTEを配置したイメージ

↑が設置したQTEの検知エリアです。

左側のQTE

左側のQTEは↑のように設定しFire1ボタンを押すようにし、制限時間を10秒とします。

Fire1ボタンにはデフォルトでマウスの左クリックが設定されています。

右側のQTE

右側のQTEは↑のように設定しJumpボタンを押すようにし、制限時間を3秒とします。

JumpボタンにはデフォルトでSPACEキー等が設定されています。

では実行してみましょう。

QTEの確認サンプル

タイマーイメージで制限時間が視覚的にわかるようになっているのでいいですね♪

右側のQTEを見るとわかりますが80%時間が経過するとストップウォッチのイメージが赤く変化してます。

最後までイメージが表示されると主人公キャラクターが倒れています。

QTEを作り終えて

今回はQTE成功時に特に何もアクションを入れていません。

地面を飛び越える時にQTEを登場させ、成功したら地面を飛び越える、失敗したら穴に落ちるという処理を作るといいかもしれませんね。

そこら辺まで作ろうとするとまた別の処理を入れてわかり辛くなると思うし、そこはまた別の機能なので割愛させて頂きます。

今回はスクリプト間の連携がちょっとわかり辛い感じになってしまいましたが、出来てしまえば設置してパラメータを変更するだけなので、

QTEをいくつか設置したい時に便利だと思います。

ぜひ参考にして作ってみてください。(^^)/

スポンサーリンク

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

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

コメント

  1. Mika より:

    かめくめ師匠、こんにちは。(*’ω’*)

    いつも幾らググっても他ではかすりもしないunity関連の貴重なTIPSをありがとうございます。
    m(__)m
    見本の実行画面のぼーっと佇むイーサンの突然死に不覚にも笑ってしまいました。(すいません)
    (;´∀`)先にカットシーンが要りますね、アニメーション連携などでまた判らないことがあったら質問してしまうと思いますが、またよろしくお願いします。m(__)m

    (そういえば今日は旧暦の正月だそうで…明けましておめでとうございます。(2回目)
    ( ´艸`))

    • こんにちは、師匠と呼ばれるほどの事が出来ないので恐縮します・・・(-_-)

      Ethanには非常にお世話になってますね、このブログのメインキャラクターですよ(謎)

      自身で作成した3Dキャラクターでないのが残念なぐらいです。

      QTE突入時に走っているアニメーションを使ってAnimatorでアニメーションスピードを遅くする演出というのも面白いかもしれませんね。

      成功時は通常のアニメーションスピードに戻して穴を飛び越える、失敗時は足を滑らせて穴の中に落ちるとか。

      そうなると主人公操作スクリプトの処理が大変になりそうですが・・・(^_^;)

      またはQTE時にはスクリプトからAnimatorのApply RootMotion?にチェックを入れることで、スクリプトでキャラクターを移動させずアニメーションの移動値を反映させる形でキャラクターを動かすようにするという手もあります。

      何はともあれちょっと大変そうではありますね・・・(-_-)

  2. ZETTA より:

    はじめまして。
    Unityでゲームを作っている者なのですが,(YoutubeのURLです)
    ttps://www.youtube.com/watch?v=ei0QeAivlk8
    このゲームのような,複数のQTEのUIを表示させ,それらを成功できなかったら
    失敗とする感じのQTEはどのように作ればできると思いますか?

    • こんにちは(^^)/

      ヘビーレインですね、なつかしいです・・・(ほとんど内容を忘れてしまいましたが)

      複数のQTEのUIを含んだQTEUIを作り、スクリプトで最初のQTE用のUIを表示してボタン押しに成功したらそのUI(パネル)を消し、次のQTE用のUI(パネル)を表示しという感じにしてはどうでしょうか?

      動画のようにするならPanelで領域を分けて作成しておき使う時に表示するという感じですね。

      QTEUIで実行しなければいけない時にそのUIだけを表示するようにします。

      失敗した時は次のQTE用UIの表示をせずQTEUI全体を非表示にし、QTEイベントを終了します。

      押さなければいけない時間や押すボタン等はQTEUI全体で管理する形になると思います。

      押さなければいけない時間や押すボタンは配列のデータとして持っておいて順番に使用するといいかもしれません。

      もしあれでしたらちょっと作ってみます。

      ただ・・・今色々作ってて時間がかかりますけど・・・・(-_-)

      動画のURLは最初のhだけ削除させて頂きました。

    • 複数のQTEに対応する機能を作成しました。

      https://gametukurikata.com/program/continuityqte

      少しヘビーレインに寄せましたが・・・プロにはかないません・・・(^_^;)

      ぜひ参照してください。

      • ZETTA より:

        返信遅れてすみません。わざわざ作成していただきありがとうございました。参考にさせていただきます。