執筆バージョン: Unreal Engine 4.22
|
はじめまして、エンジニアの片平です。
今回はUE4.22で新規追加された”TimeSynth“を使用し、BGMに同期した演出を作ってみます。
TimeSynthとは
新たなオーディオコンポーネントであり、従来のUE4の機能では困難だったオーディオ再生位置の正確な管理が可能となります。結果として、インタラクティブミュージックや音楽に合わせた視覚的演出がバツグンに作りやすくなります!
その他に、TimeSynth には音量のグループ化、フィルター、フィルターを時間的に変化させるエンベロープ機能なども搭載されていますが、これらの機能についてはこの記事では扱いません。
なお、この機能は早期アクセスのため今後のアップデートによっては仕様が変更される可能性があります。ご留意ください。
それでは、今回は TwinStickShooter プロジェクトを改造して以下の3つの機能を実装してみようと思います。
① BGMをループさせる
② BGMに同期したアニメーション
③ BGMに同期したオーディオ再生
~準備~
プラグインの有効化
プロジェクトを開いたら、まず Audio>TimeSynth プラグインを有効にします。

再起動を求められるので再起動します。
オーディオのインポート
使用するオーディオファイルをまとめてインポートしておきます。

BGM … 常に後ろで流れているループBGMです。トランス風味。
melody1~3 … 敵を破壊した時に鳴るメロディです。
TimeSynthComponentの追加

今回は TwinStickPawn に TimeSynthComponent を追加しました。
レベルブループリントで使う場合は Begin Play に AddTimeSynthComponent を繋ぎます。
重要なBPノード解説
■PlayClip

指定した TimeSynthClip を再生します。再生タイミングは TimeSynthClip の設定で指定した ClipQuantization になります。(後述)
戻り値のハンドラで再生停止やフェードアウトの制御ができます。
■AddQuantizationEventDelegate

指定した QuantizationType のタイミングで OnQuantizationEvent デリゲートに繋いだイベントを呼び出します。

デリゲート先のイベントには QuantizationType 、 NumBars、 Beat が渡され、現在の再生位置が特定できます。
BPの作成
以下のように TwinStickPawn の Blueprint を組みます。
(クリックで拡大)
SetBPM でBPMを設定します。今回のBGMはBPM = 147なので147.0を設定します。
AddQuantizationEventDelegate ノードで4小節毎に呼ばれるイベント 4BarEvent と、1拍毎に呼ばれるイベント BeatEvent を作ります。
Activate で TimeSynthComponent を有効化します。
~①ループBGMを鳴らす~
TimeSynthClipの作成
コンテンツブラウザの右クリックメニューから サウンド>TimeSynthClip を選択し、新たな TimeSynthClip を作成します。

作成した TimeSynthClip を開き、各種設定をします。
(クリックで拡大)
主要な部分を解説します。
<Clip>
Sounds : 新しいエレメントを追加し、Sound Wave にBGM用のオーディオである「BGM」を選択します。
<VolumeControl>
Fade in Time : フェードインさせる必要はないので NumBars、Beats 共に0にしておきます。
Apply Fade Out : フェードアウトさせる必要はないのでチェックを外しておきます。
<TimeControl>
ClipDuration : clip の長さです。今回のBGMは4小節ちょうどの長さのため NumBars = 4、NumBeats = 0を設定します。
ClipQuantization : クリップを再生するタイミング(間隔)の設定です。BGMの場合は小節の頭から鳴って欲しいため 1Bar を選択します。
ちなみに Bar = 小節、Beat = 拍 です。
BPの作成
(クリックで拡大)
PlayClip を追加します。ゲーム開始時に再生を開始し、以降は 4BarEvent で4小節毎に鳴らすようにしています。
BGMが切れ目なくループ再生されてますね。
~②BGMに同期したアニメーション~
ターゲットがBGMに合わせて鼓動するようにしてみます。
BPの作成
(クリックで拡大)
BeatEvent から全てのターゲットActorの BeatProduction を呼びます。
ちなみに BeatProduction ではタイムラインでスケールを変動させて鼓動アニメーションを実装しています。
音楽の拍に合わせてターゲットが鼓動します!
~③オーディオをBGMに同期させる~
ターゲットを破壊した時、賑やかしのメロディが入るようにします。
TimeSynthClipの作成
破壊効果音用の TimeSynthClip を作成します。
(クリックで拡大)
<Clip>
Sounds : 3つのメロディをランダムで鳴らすため、3つ設定しています。
※RondomWeightで抽選に重みを付けることもできますが、今回は均等にしたいので 1.0 のままです。
<TimeControl>
ClipQuantization :1小節の始まりと同時に鳴らしたいので1Barにしています。
BPの作成
(クリックで拡大)
単純にターゲット破壊時にこのイベントを呼べばOKです。自動的に次の1小節の始まりを待って同期再生してくれます。
※同タイミングで複数の発音すると煩くなるので実際の実装時には同時発音制御が必要です。
ターゲットを破壊した後にBGMと同期したメロディが流れました!
おまけ
自機ショットを1/16音符で同期させたり、ライトの色を拍に合わせて切り替えたりしてます。
音楽と同期する演出は非常に効果的です。工夫次第で色々出来ると思うので是非試してみてください!
この機能で本格的なインタラクティブミュージックもやってみたいです…