【Unity / Audio】STYLYシーン上で音響効果を切り替える

今回の記事ではオーディオフィルターを使って、STYLYシーン上でオーディオエフェクトを切り替える方法について紹介していきます。
インタラクションとフィルターによる音響効果の変化を紐づける事で、よりインタラクティブなシーンを作れるようになるはずです。

注意点ですが、今回紹介するやり方は現在Oculus Quest版のSTYLYアプリでのみ機能します。
WebやSteam版アプリでは機能しません。

スフィアをクリックした時にエフェクトがかかる様子

スフィアをクリックした時にエフェクトがかかる様子

サンプル

STYLY GALLERYからサンプル空間を体験できます。
シーン上のスフィアをクリックすることで、それぞれのエフェクトをオン/オフできます。
左から順に

  • 低音カット
  • 反響効果追加
  • コーラス効果追加

のエフェクトがかかるようになっています。
こちらのシーンはOculus Quest版のSTYLYアプリでのみ動作します。
そのため、音の変化やビジュアライザの動きを確認したい方はアプリからシーンをご確認ください。

事前準備

今回の記事ではPlayMakerを使用します。

UnityのプラグインであるPlayMakerをあらかじめインストールしておきましょう。

はじめてPlayMakerを使用する人は、あらかじめ以下の記事を一読することで、理解を深められます。

また、今回はUnityのオーディオシステムとPlayMakerを組み合わせてシーンを制作します。
そのため、前提知識としてUnityのオーディオシステムの理解があるとスムーズにシーンが作成できます。

オーディオシステムの基礎的な知識は以下の記事で解説しています。
Audio Source, Audio Listenerなどの基本的なオーディオコンポーネントについて知りたい方はご参照ください。

実装する動き

今回はPlayMakerを使ってスフィアがクリックされた時、流れている音にエフェクトがかかるようになる仕組みを作成します。

Unity内で音にエフェクトをかけるにはAudio Filterコンポーネントを追加する必要がありますが、このコンポーネントはAudio Listenerをもつオブジェクトに追加しなければいけません。

しかし、Oculus Quest版のSTYLYアプリでは、Audio Listenerはデフォルトのカメラではなく起動後に追加されるSTYLY_Playerオブジェクト内のメインカメラに存在します。

そのため

  • シーンのメインカメラの位置を取得
  • スフィアがクリックされた時、メインカメラがフィルターコンポーネントを持っているかを判定
  • フィルターコンポーネントを持っていない場合にコンポーネントを追加、持っている場合コンポーネントを削除
    という手順で目標の動きを実装していきます。

音源の用意

まず使用する音源を用意しましょう。
今回のサンプルシーンではこちらのサイトの音源を使用させて頂いています。

魔王魂:https://maoudamashii.jokersounds.com/

音源が用意できたらUnityプロジェクトにインポートし、シーン内に配置しましょう。
今回はBGMとして使用するため、Play On AwakeとLoopをオンにし、Spatial Blendを2Dにします。

Audio Sourceの設定

Audio Sourceの設定

これで音源の用意は完了です。

PlayMakerの設定

次にPlayMakerの設定をしていきましょう。

スフィアを設置し、スフィアにFSMを追加してください。
このスフィアをクリックすると音源にReverb FilterがかかるようにPlayMakerを設定していきます。

今回使うオブジェクト

今回使うオブジェクト

カメラを取得

まずメインカメラを取得し、camera変数に格納します。
こうする事でcamera変数にコンポーネントを追加してエフェクトをかけられるようになります。

メインカメラを取得する

メインカメラを取得する

フィルターコンポーネントを追加

次のStateでAudio Fliterコンポーネントを追加します。
アクションブラウザから「Add Component」を検索して追加します。
追加するコンポーネントは「UnityEngine.AudioReverbFilter」です。

カメラにコンポーネントを追加

カメラにコンポーネントを追加

あとで値を変更できるように、このコンポーネントも変数に格納します。
Variablesタブを開き、Object型でreverbという名前の変数を追加します。

reverb変数をFSMに追加

FSMにreverb変数を追加

変数を追加したら、Object TypeをUnityEngine.AudioReverbFilterに変更してください。
再びAdd Componentアクションに戻り、Store Componentにreverbを指定します。

Object Typeを変更

Object Typeを変更

次にReverbフィルターの効果を設定します。
Set PropertyアクションをStateに追加し、Target Objectをreverbに設定します。
ここでReverbフィルターのプロパティの値を変更して効果を作ります。

SetPropertyアクションを追加

Set Propertyアクションを追加

今回はわかりやすいように、強めの効果を設定してみましょう。
Decay HF Ratioを2Decay Timeを20にします。

アクション内で効果を設定

アクション内で効果を設定

プロパティを設定できたら、State1にFINISHEDイベントを追加し、遷移先にState2を指定してください。

State2への遷移を追加

State2への遷移を追加

再生ボタンを押した時にフィルターがかかった状態になっていれば成功です。

インタラクションを実装

次にインタラクション部分を実装します。

今回は「UI POINTER DOWN」というイベントを使ってクリックインタラクションを実装します。
State1にUI POINTER DOWNイベントを追加してください。
このイベントを使うことで、クリック時にStateを遷移できます。

UI POINTER DOWNイベントを追加

UI POINTER DOWNイベントを追加

イベント追加後、FINISHEDイベントを削除し、UI POINTER DOWNの遷移先をState2に指定します。
これでクリックインタラクションが追加できました。

UI POINTER DOWNの遷移先を設定

UI POINTER DOWNの遷移先を設定

実際にVR上で確認してみましょう。
STYLYのローカルプレビューツールを使えばすぐにVR上でシーンを確認できます。
ローカルプレビューツールの使い方は以下の記事で紹介しています。

ローカルプレビューツールでシーンを起動し、スフィアをクリックした時にフィルターがかかるようになっていれば成功です。
また、Unity上で挙動の確認をしたい場合は、UI POINTER DOWNと同様の手順でStateにMOUSE DOWNなどのイベントを設定すると、Unityゲームビューをクリックするなどの動作をする事で確認できます。

フィルターコンポーネントを削除

最後に、フィルターがある状態でクリックした場合にフィルターを削除する事でオン/オフが切り替えられるようにしましょう。

まず、Stateの名前をわかりやすくします。

  • State1 → Initialize
  • State2 → Add Filter
    に名前を変更してください。

今回は「Has Component」というアクションを使ってフィルターがかかっているかどうかを判定します。
Has Componentはオブジェクトが指定のコンポーネントを持っているかを判定し、持っていればtrue、持っていなければfalseに指定したイベントを呼び出すアクションです。

Has Componentアクションの使い方

Has Componentアクションの使い方

新しくStateを追加し、InitializeのUI POINTER DOWNの遷移先を追加したStateに変更してください。
このState内で、カメラがフィルターを持っているかどうかを判定します。

追加したStateの名前をCheckFilterにし、Has Componentアクションを追加してください。
Game Objectの指定をcamera、判定するコンポーネントの指定をUnityEngine.AudioReverbFilterにします。

新しいStateを追加、Has Componentアクションを追加

新しいStateを追加、Has Componentアクションを追加

次に呼び出すイベントを設定します。
今回は単純にTrueのときtrueイベントが、Falseのときfalseイベントが発生するように設定しましょう。

各Event欄をクリックし、「New Event」からtrueイベントとfalseイベントを作成します。
イベントが作成できたらStateを右クリックし、Add TransitionからそれぞれのイベントをStateに追加します。
そしてフィルターがないとき、つまりfalseのときにAddFilterに遷移するよう矢印を繋ぎます。

CheckFilterがfalseの時、Add Filterへ遷移

CheckFilterがfalseの時、Add Filterへ遷移

また、フィルター追加後にスフィアがクリックされたときにもう一度CheckFilterに遷移するよう、Add FilterにUI POINTER DOWNイベントを追加します。
その後、イベントの遷移先をCheckFilterにします。

Add FilterからCheckFilterへの遷移を追加

Add FilterからCheckFilterへの遷移を追加

これでフィルターがない状態でスフィアがクリックされた時、フィルターがオンになるように設定できました。

クリック時のPlayMakerの様子

クリック時のPlayMakerの様子

次にフィルターがある状態でスフィアがクリックされた時、フィルターがオフになるように設定します。

FSMを右クリックしてStateを追加し、RemoveFilterという名前に変更してください。
このRemoveFilterの中でFilterコンポーネントを削除してフィルターをオフにします。
CheckFilterのtrueイベントの遷移先にRemoveFilterを指定してください。

コンポーネントの削除には「Destroy Component」アクションを使います。
Game Objectにcameraを選択し、削除するコンポーネントを指定します。
ここではAudio Reverb Filterを指定します。

削除するコンポーネントを指定

削除するコンポーネントを指定

これでフィルターコンポーネントが削除されるようになりました。
AddFilterと同様にRemoveFilterにUI POINTER DOWNイベントを追加し、CheckFilterへの遷移を追加しましょう。

RemoveFilterからCheckFilterへの遷移を追加

RemoveFilterからCheckFilterへの遷移を追加

ローカルプレビューツールを起動し、スフィアをクリックする度にフィルターが切り替わるようになっていれば成功です。

PlayMakerの様子

PlayMakerの様子

異なるエフェクトを追加する

違うフィルターがかかるスフィアを追加しましょう。
先ほど作成したスフィアを複製し、横に並べます。

Chorus Filterの作成

まずはコーラスフィルターを切り替えられるように設定します。
新しく追加したスフィアのFSMのVariablesタブを開きます。

以下のように変更してください

  • 変数reverbの名前をchorusに変更
  • 変数chorusのObject TypeをAudio Chorus Filterに変更
  • CheckFilter内のHas Componentアクションで判定に使うコンポーネントをAudio Chorus Filterに変更
  • AddFilterで追加するコンポーネントをAudio Chorus Filterに変更
  • RemoveFilterで削除するコンポーネントをAudio Chorus Filterに変更

コーラスフィルターの場合は少し処理が増えます。 
Audio Chorus Filterはコンポーネントを追加後、待ち時間を入れないとプロパティの変更が反映されません。
そのためAddFilterでAudio Chorus Filterを追加後、新しくSet PropertyというStateを作成します

Add FilterのUI POINTER DOWNイベントをFINISHEDイベントに変更し、遷移先をSet Propertyにします。
その後、Set PropertyにUI POINTER DOWNイベントを追加し、遷移先をCheckFilterにしてください。

新しいStateと遷移を追加

新しいStateと遷移を追加

待ち時間を作るため、Add Filterの最後に「Wait」アクションを追加し以下のように設定してください。

Add Filterに待ち時間を設定

Add Filterに待ち時間を設定

Set Property内で以下のようにプロパティを設定しましょう。

ChorusFilterのプロパティを設定

ChorusFilterのプロパティを設定

シーンを再生し、スフィアをクリックしてフィルターの切り替えができれば成功です。

High Pass Filterの作成

再びReverbフィルターを追加するスフィアを複製します。
コーラスフィルターと同様に変数名とコンポーネントを変更します。

以下のように変更してください

  • 変数reverbの名前をhighPassに変更
  • 変数passのObject TypeをAudio High Pass Filterに変更
  • CheckFilter内のHas Componentアクションで判定に使うコンポーネントをAudio High Pass Filterに変更
  • Add Filterで追加するコンポーネントをAudio High Pass Filterに変更
  • Remove Filterで削除するコンポーネントをAudio High Pass Filterに変更

High Pass FilterはReverb Filter同様、AddFilter内でプロパティをセットする事ができます。
以下のように設定してみましょう。

Audio High Pass Filterの設定

Audio High Pass Filterの設定

再生し、フィルターが切り替わるようになっていれば成功です。

オーディオビジュアライザを追加する

シーンに動きをつけるために、サンプルのようなオーディオビジュアライザを追加してみましょう。
PlayMakerを使えばとても簡単に実装できます。

PlayMakerで作るオーディオビジュアライザー

PlayMakerで作るオーディオビジュアライザ

空のGame Objectを作成し、SpectrumInitializerという名前に変更してください。
このGame Objectを使って音の周波数スペクトルを取得します。

SpectrumInitializerにFSMを追加し、「Init Audio Spectrum」アクションを追加します。
アクション内の設定は以下のように設定してください。

Init Audio Spectrumアクションを追加

Init Audio Spectrumアクションを追加

次に、音に合わせて変化するオブジェクトを配置します。
Cubeを作成し、FSMを追加してください。
FSM内に「Get Audio Spectrum」アクションと「Set Scale」アクションを追加し、以下の画像のように設定してください。

スペクトルを取得し、3DモデルのY方向の大きさにセットする

スペクトルを取得し、3DモデルのY方向の大きさにセットする

完成したCubeを複製しGet Audio SpectrumのIndexを1ずつずらして横に並べて配置します。

この状態で再生してみましょう。
音に合わせてCubeの高さが切り替わるようになっているはずです。
GIF画像のため少しわかりにくいですが、スフィアをクリックするとエフェクトがかかり、ビジュアライザの動きも変化していることがわかります。

スフィアをクリックすると低音部がカットされる

スフィアをクリックすると低音部がカットされる

使用したアクションの項目の詳細な説明は以下の記事で解説しています。
オーディオビジュアライザに興味のある方はぜひご参照ください。

STYLYにアップロードする方法

シーンが完成したら3DモデルをSTYLYにアップロードしてみましょう。

STYLYアカウントを作成する

アカウント作成方法

STYLYにアップロードする方法

UnityからSTYLYにアップロードする方法

今回はシーンの中でオーディオフィルターを使ってエフェクトを切り替える方法を紹介しました。
プレイヤーのアクションに応じて音にエフェクトをつけるなどいろいろな活用法があります。
今回の記事が皆様の創作の手助けになれば幸いです。