📝

技術記事10本書く

【Unity】Timelineからデバイスの振動を制御する【イージング付き】 - Qiita
この記事は Unity Advent Calendar 2020 12日目の記事です。昨日は@__poosukeさんの『 Unityから考えるDI 』の記事でした。 先日リリースしたVRゲーム『 ALTDEUS: Beyond Chronos(アルトデウス: ビヨンドクロノス) 』というゲームでは、一部シーンでTimelineを使った演出があります。そのシーンでは臨場感を表現するためデバイスの振動を組み合わせているのですが、これをTimelineを作成するアニメーターさんが扱えるようにしたところ、非常に素晴らしい体験が出来上がりました。 今回はVRのハンドコントローラー(特にOculus)を例に、その方法を紹介したいと思います。 Marker機能を使うと、Timelineのシークエンス上にトリガー(下図の逆ティアドロップみたいな形のやつ)を設置し、そこから任意の処理を呼ぶことができます。 参考: 【Unity】Timelineからメソッドを呼ぶ新機能 「Marker」と「Signal、Signal Receiver」 - テラシュールブログ 詳しくは上の記事で丁寧に説明されているので割愛しますが、大体こんな感じのコードを書いています。Timelineが該当のマーカーに到達すると INotificationReceiverを継承した MonoBehaviour にイベントが発行されるので、その中で具体的な処理(今回は振動)を書くイメージです。 次に振動のパターンを細かく指定できるようにしていきます。先ほどの VibrateMarker を見ていただくと分かるように、Inspectorで値の指定が可能になっています。この辺りがSignalとの違いでしょうか。 そこで今回は以下のパラメータを実装しました。 (Time: Marker標準のパラメータ、開始位置が秒/フレーム数として表示されている) Hand Type: 対象となるVRハンドコントローラーを指定する独自のenum(Both, Left, Rightがある) Duration: 持続する秒数 Power: 振動の強さ(振幅) Frequency: 振動の細かさ(周波数) Should Easing: イージングの有無 Power Ease: 振動の強さに対するイージングの種類 コードはこんな感じ 次に、これを受け取る側の処理です。一部抜粋することこんな感じ。 Markerが呼ばれると OnNotify というイベント関数が発火します。ただしどのマーカーであるかはわからないので、 asを使って型の変換を試みて、 VibrateMarkerであれば処理を続けるという分岐を書いています。マーカーが複数ある場合は is とかで処理を分けることになる気がします。 振動の処理は部分はこんな感じです。複数プラットフォームの対応をするため、ラッパーを呼んでいます。 勘のいいひとはお気づきかもしれませんが、Oculusの振動メソッド OVRInput.SetControllerVibration (frequency, amplitude, controller)には継続時間の指定がありません。なので、 VRPlatformManager.Platform.Vibrate() の内側で以下のような処理を呼んで疑似的に実現しています。(2.0秒間振動続けると自動で停止する仕様があるため、2秒ごとにコールしなおしています) TimelineController の全文は以下です。両手別々にイージング処理をしている関係で冗長になっていますが、大した処理はしていません。 ポイントは LastPowersで最後の振動の強さを保持しています。イージング処理をする場合は終点を指定する形になるので前回の値が必要になるのです。前回の振動中に呼ばれた場合はその時点から上書きされますが、一度振動が終わってからイージングが呼ばれる場合もあるので、終了時点で.OnComplete (() => LastPowers[handType] = 0f); を呼ぶことを忘れないようにします。 やっていることはシンプルですが、組み合わせるとかなり強力なエディタ機能になったと感じました。よかったら参考にしてみてください! 最後に宣伝ですが、VRゲーム『 ALTDEUS: Beyond Chronos(アルトデウス: ビヨンドクロノス) 』では今回の技術を活用した臨場感あふれるマシンアクションを楽しめます。興味がある方はぜひやってみてください! さて、 Unity Advent Calendar 2020 13日目の記事は@yunoda ...