レッスン 8

目次

MusicリージョンのStateを設定する(Setting a Music Region State)

インタラクティブミュージックをゲームに統合する際に、楽曲をゲーム内の様々なイベントやアクションに関連付けることが多く、プレイヤーの頭の中には、音楽セグメントと、そのイベントやアクションの間の関連性が植え付けられます。ミュージックシステムのつくり方は、いくつもあります。例えば、ゲーム内のプレイヤーの進捗状況やポジションに基づいて音楽を切り換えたり、プレイヤーに聞きたい音楽を選ばせたり、この2つを合わせたりできますが、多くの場合、ある時点でアクティブになる音楽ピースは、1つ(または同じリズムまたはキーの、多数の音楽を集めたもの)にして、サウンドスケープを混乱させないようにしてあります。こういったシナリオでは、現在の音楽のStateをコントロールするのにState機能が理想的で、グローバルスコープで作用してくれます(ゲームオブジェクトとグローバルスコープに関しては、 レッスン 5 で説明)。

これから、 プレイヤーがVillageに入ったときに、ミュージックのStateを変更する方法を説明します。Villageの周りにTriggerボリュームを追加し、次にスクリプトで、Playerの場所に基づいてStateを設定します。

  1. Unityのメニューで、 Audiokinetic > Certification > 301 > Lesson 8 を選択し、 Setting a Music Region State を選択します。

    最初に、Villageエリアの形に合ったTrigger形状を選びます。

    Villageを上から観察すると、なんとなく丸いので、SphereのTriggerでうまく覆えると思われます。

    [ヒント]

    SphereのTriggerはTriggerタイプの中でも最も効率のよいものの1つで、一部の形状よりも少ないCPUで済みます。

  2. Sceneビューを調整し、Villageエリアが見下ろせるようにします。

    [注釈]

    Hierarchyのゲームオブジェクトをマークしていないか、注意してください。もし分からなければ、ゲームオブジェクトの下の空いた場所をクリックしてください。

  3. Hierarchyで空いた場所を右クリックしてから 3D Object を選択し、 Sphere を選択します。

  4. Moveツール、RotateツールScaleツール を使い、SphereでVillageエリア全体を覆うようにします。

    それでは、Trigger形状として違うメッシュを設定して内側が見えるようにし、Sphere Colliderの中に入れるように、Triggerに設定します。

  5. Inspectorで、Sphere Colliderの Is Trigger を有効にします。

    もしSphereの形が全く見えない方がよければ、Mesh Rendererを完全に無効にします。テストでは、トリガーに入るのが目で分かるように、Sphereの形を半透明の素材にしてください。ここでSphereを描くのに使うのは、 レッスン 3 で使った既成のTrigger_RedというMaterial です。

  6. Projectビューで Trigger_Red を検索し、 Trigger_Red のMaterialをSphereゲームオブジェクトの上までドラッグします。

    次にSphere形状のTriggerのステートを設定するためのスクリプトを追加します。

  7. Sphereに新しい SetMusicState というスクリプトを追加し、それを開きます

  8. レッスン 4 で説明したとおり、基本的なStart()とUpdate()ファンクションが定義されているスクリプトが準備できました。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
    
        // Use this for initialization.
        void Start () {
            
        }
        
        // Update is called once per frame.
        void Update () {
            
        }
    }

    これらのファンクションは使わないので、SetMusicStateクラスの中にあるものを、すべて削除してきれいにします。

  9. SetMusicStateの波括弧内のすべての行を選択し、Backspaceを押します。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
    
    }

    プレイヤーがTriggerに入ったことを検知するには、TriggerがコールするOnTriggerEnterファンクションが、もしスクリプトにあれば、使えます。このファンクションは、 レッスン 1 で説明したAkEventの Trigger On の'AkTriggerEnter'という選択肢と、名前も機能も似ています。

  10. 空白の場所に void OnTriggerEnter と書きます。

    Visual Studioがドロップダウンメニューを表示します。OnTriggerEnterファンクションを提案していますが、これはまさしくあなたの探しているものです。OnTriggerEnterの項目をクリックすると、Visual Studioが自動的にこのファンクションを完成させてくれます。Visual Studiがファンクションを自動入力すると、同時にアクセス修飾子を private に宣言してくれるので、このファンクションはSetMusicStateクラスの中からしか使うことはできません。

    [注釈]

    もしコードエディタにドロップダウンが表示されなければ、以下のように自分で入力すればいいのです。

  11. ドロップダウンで OnTriggerEnter をクリックするか、 private void OnTriggerEnter(Collider other){} と入力して行を完成させます。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
        private void OnTriggerEnter(Collider other){
        
        }
    }
    

    OnTriggerEnterの括弧内に、Collider変数の'other'があります。SphereゲームオブジェクトのColliderが、ほかのCollider(Triggersを含む)を検知すると、OnTriggerEnterファンクションを、検知したものとともに、コールします。つまり'other'変数は、このTriggerに入ってきたばかりのColliderのことです。例えば、Playerゲームオブジェクトが作成したばかりのSphere Triggerに入ってくると、OnTriggerEnterと、Player上にあるColliderコンポーネントを参照先とする'other'変数が、コールされます。

    Stateを切り換えるのは、PlayerゲームオブジェクトがTriggerに入ってきたときだけなので、入ってきたColliderに"Player"のタグが付いているかを確認します。それには、'if文'と、CompareTag()ファンクションを、入ってきたColliderオブジェクトに対して使います。それでは、1つの'if文'を詳しくみていきます。

    if文とは、インプットを受け取り、ある条件で判断し、条件で判断した結果が'true'であれば、プログラマが1つのコードを実行させるものです。一方、if文で'false'と返ってくれば、そのコード部分をスキップします。if文の書き方は、'if'と書き、続けて括弧'()'の中に判断するためのブーリアン式を入れ、波括弧'{}'に実行すべきコードを入れるだけです。それでは、非常に基本的な例を見てみます。

        if (Number == 42){
            print("Number is 42.");
        }else {
            print("Number is not 42.");
        }
    

    それでは、演習に戻ります。if文の括弧内で、CompareTag() ファンクションを、入ってくるColliderオブジェクトに対して使い、'other'ゲームオブジェクトがPlayerであるかどうかを判断する必要があります。そこでPlayerのタグ名(タグの名前もPlayer)を、CompareTag ファンクションの括弧内の文字列として書けば、true比較の結果がtrueかfalseなのかを、CompareTag ファンクションが返してくれます。

    [注釈]
    文字列とはテキストを格納する方法で、文字列を宣言するには、テキスト部分を2つの引用符("")でカプセル化します。

  12. OnTriggerEnterファンクションの波括弧内に、 if(other.CompareTag("Player")){ } と入力します。

    public class SetMusicState : MonoBehaviour {
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                
            }
        }
    }

    [注釈]

    コードエディタが自動的に終わり波括弧を追加してくれることがあるので、終わり波括弧が余分にないか、注意してください。

    この"if文"内にStateを設定すれば、プレイヤーがTriggerに入ったことが原因だと分かります。次に、Wwise-TypeのStateプロパティを作成します。

  13. クラスのトップに public AK.Wwise.State OnTriggerEnterState; と書いて、Wwise-TypeのStateプロパティを宣言します。

    public class SetMusicState : MonoBehaviour {
        public AK.Wwise.State OnTriggerEnterState;
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){

    これで、MusicStateをOnTriggerEnter()ファンクションの中に設定できます。

  14. If Statement の中に OnTriggerEnterState.SetValue(); と書き、 スクリプトを保存 します。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
        public AK.Wwise.State OnTriggerEnterState;
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }
        }
    }

  15. UnityのInspectorのSetMusicStateスクリプト内で、 OnTriggerEnterState プロパティを開き、 MusicStates > Music_Regions を展開して Village を選択します。

    以上です。それでは、試してみてください。

  16. Playモードに入り、Sphere Triggerに駆け込みます。

    Training Areaでスポーンすると、Ambient MusicのPlaylist Containerが聞こえてきます。そしてSphere Triggerに入ると、Village MusicのPlaylist Containerの音楽に変わります。

    この処理で、入るときのStateの設定ができました。しかし出たときに、StateがAmbient MusicのPlaylist Containerに戻りません。そこで別のWwise-Type Stateクラスプロパティを追加し、Triggerを出るときのStateを設定してください。それでは、Playモードを終了してください。

  17. コードエディタに戻り、OnTriggerEnterStateプロパティの宣言の下に空白の行を入れ、そこに public AK.Wwise.State OnTriggerExitState; と書きます。

    public class SetMusicState : MonoBehaviour {
        public AK.Wwise.State OnTriggerEnterState;
        public AK.Wwise.State OnTriggerExitState;
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }
        }
    }

    プレイヤーがTriggerを出たことを検知するのに、OnTriggerExit()ファンクションを使います。コードを書く時間を少し節約するために、OnTriggerEnter()ファンクションをコピーし、それをOnTriggerExit()ファンクションにします。

  18. OnTriggerEnter() ファンクション全体を、波括弧も含めて選択し、次に右クリックして Copy を選択します。

  19. OnTriggerEnter()ファンクションの閉じ括弧の下に空白行を追加し、その行を右クリックして Paste を選択します。

    public class SetMusicState : MonoBehaviour {
        public AK.Wwise.State OnTriggerEnterState;
         public AK.Wwise.State OnTriggerExitState;
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }
        }
        
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }
        }
    }

  20. OnTrigger Enter の名前をOnTrigger Exit に変更して、OnTrigger EnterState の名前をOnTrigger ExitStateに変更してから、 スクリプトを保存 します。

        private void OnTriggerExit(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerExitState.SetValue();
            }
        }

    最後に、OnTriggerExitStateプロパティをアサインし、試してみてください。

  21. Unity Inspectorで On Trigger Exit State プロパティを開き、 MusicStates > Music_Regions を選択して Nowhere を選択します。

  22. Playモードに入り、Sphere Triggerに駆け込みます。

    前と同じように、Village音楽の再生が始まるはずです。

  23. Sphere Triggerを走って出ます。

    スクリプトに変更点を加えたので、ここでAmbientミュージックの再生が始まるはずです。それでは、Playモードを終了してください。

この方法は設定が非常に早く使うのも簡単ですが、Stateを設定するためのTrigger同士が重ならないようにすることが重要で、さもないとStateのコンフリクトが発生するかもしれません。これについては次のセクション'交差するStateエリアのシステムをつくる'で詳しく説明します。