たくあんポリポリ

勉強したことを載せていきます。最近、技術系の記事はZennに書いています。(https://zenn.dev/chittai)

LeapMotion + OcusulRift でVRで音楽を聞く環境作成を目指してみた

音楽を聞くことをもっと楽しめたらなと思い、LeapMotionとOculusRiftを使用して、UIを操作することで音楽似合わせて色々とアクションが起こせるようにしてみました。

今回つくったもの

<動画>
youtu.be

やりたいこと

音楽のビジュアル化に加えて、なにかインタラクティブな要素を入れられたら面白いかな~と思っていたので、今回はOculusRfitに加えて、LeapMotionを使って実装してみました。

使用したツール / 環境

  • Unity 2017.3.1f1
  • UniRx
  • LeapMotion
  • Rhythm Visualizator Pro
  • SkyBox Pack 8k UHD

どんなことをしたのか

今回目標としていたのは、音楽のビジュアル化とインタラクティブな操作です。

音楽のビジュアル化

まず、音楽のビジュアル化についてですが、アセットのRhythm Visualizator Proを使用しました。
音楽を指定すると、スペクトラム・アナライザでバーを表示してくれるので、自分の好きな音楽を設定します。私の場合は、「Ubiquitous dB」にしました。細かい使い方は別途書くかもしれないです。とりあえず表示方法をCircleに設定して円で表示されるようにしました。

インタラクティブの要素

インタラクティブとは対話・双方向といういみなので、UIでの操作・演出をするという意味では少し違うのかもしれないですが、今回はUIを操作してアクションを起こすことで、音楽の演出を聞き手側を主観として表現しているので、インタラクティブって言っていいかなって思ったけど結果的にインタラクティブにならなかった感じです。ちなみにできることは以下です。

  • 周りにあるパーティクルの色を変える
  • 花火を打ち上げる
  • 雨を降らせる、雪を降らせる、桜の花びらを降らせる

実装について

音楽のビジュアル化はアセットだけなので、UI部分について記載します。

UIのオブジェクト

これは、LeapMotionのサンプルから拝借しました。

https://developer.leapmotion.com/unity#5436356

上記URLから、 Interaction Engine の最新パッケージをダウンロードして、Unityでインポートします。

SamapleのBasicUIを開き
f:id:c_taquna:20181028232437j:plain

Cube UI Panel をPrefab化しました。
f:id:c_taquna:20181028232602j:plain

これを自分のシーンに配置すれば、準備は完了です。

パーティクルの色の変更方法

今回、UIのボタンをスライドすることでパーティクルの色が変更できるようにしました。スライドすると、HSVの値が変更されてそれがパーティクルに反映されています。左側にあるボタンは平面をスライドさせることで、HSVのHとV(HueとBrightness)を変更して、下にあるスライダーはS(Saturation)を変更しています。値の取得方法としては、すでにLeapMotionのスクリプトでVerticalとHorizontalの値が定義されていて、UIを操作することで値が変更されるのでその値を取ってきます。さらに、ReactivePropertyでHSVの値を定義して、取ってきた値を代入することで値が変更され、その後の処理が動くようにします。今回は3つのReactivePropertyの値を変更する必要があったので、Cobimelatestで3つの値をまとめました

最後に、UnityEngine.Color.HSVToRGB(list[0], list[1], list[2]); で HSVをRGBに変換するメソッドを用いて完成です。

Observable
    .CombineLatest(particleColorComponentsInstance.hueProperty,
                   particleColorComponentsInstance.saturationProperty,
                   particleColorComponentsInstance.brightnessProperty
                   )
    .Subscribe(list =>
    {

        hueText.text = "hue     :  " + list[0].ToString();
        saturationText.text = "saturation     :  " + list[1].ToString();
        brightnessText.text = "brightness     :  " + list[2].ToString();
        
        foreach (Transform particle in particleParent.transform)
        {
            ParticleSystem.MainModule par = particle.GetComponent<ParticleSystem>().main;
                par.startColor = 
                    UnityEngine.Color.HSVToRGB(list[0], list[1], list[2]); ;
        }
    }
    );

花火を打ち上げる方法

(メモ)PichDetectorを使用して、オブジェクトを作成

雨を降らせる、雪を降らせる、桜の花びらを降らせる方法

(メモ)コールバック関数でInstantiateを使用

感想