【Unity】Voice ProのデモをWebGLでビルドしても上手くいかない件

この記事は、WebGLでのボイスチャットを実現する[Voice Pro](https://assetstore.unity.com/packages/tools/input-management/voice-pro-webgl-mobile-desktop-169274?locale=ja-JP)に関する記事です。

# Voice Proのデモをそのままビルドしてもマイクがうまく作動しない
PUN2とVoice Proをそのままインポートして、PUN2の設定を済ませた後、
`FrostweepGames/VoicePro/Examples/Demo/VoiceDemo.scene`
を開いて、VoiceProオブジェクトの`Debug Echo`にチェックをつけて、エディタ上で再生すると、<strong>Rキーを押しながら</strong>話すと、自分の声が返ってきます。うまく動作していますね。

次にこのシーンをBuild & Runしてみて、Rキーを押しながら話すと、声が返ってこない...
これはマイクがうまく動作できていないのです。

# Microphoneのリフレッシュが必要
Voice ProはMicrophone Proを使用しています。そのMicrophone Proのデモとして[こちらが提示されています。](https://unitydemos.frostweepgames.com/assetstore/microphone-webgl/)
右上のマイクリストに注目してください。

<strong>マイクを許可する前</strong>は、`Microphone 1`と表示されています。
![69.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602537/55e42964-e671-de97-c0ab-9abf50de196f.png)

しかし、マイクを許可した後、<strong>Refresh Devicesを二回押すと</strong>各々のマイク名に更新されます。
![70.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602537/4c78aa60-fae8-5bdb-e89c-7255978bbcee.png)

そこで、マイクを許可していても、<strong>Microphone 1になっている間はマイクが動作しません</strong>
ちゃんとリフレッシュしてMicrophone1からちゃんとしたマイク名に更新する必要があるんですね。

そこでどうリフレッシュするのか。
このデモのリフレッシュ部分のスクリプトを抜粋します。

```C#:Example.cs
private void RefreshMicrophoneDevicesButtonOnclickHandler()
		{
            //マイクリストの更新
            CustomMicrophone.RefreshMicrophoneDevices();

            if (!CustomMicrophone.HasConnectedMicrophoneDevices())
                return;

            //ポップダウンリストの更新
            devicesDropdown.ClearOptions();
            devicesDropdown.AddOptions(CustomMicrophone.devices.ToList());
            DevicesDropdownValueChangedHandler(0);
        }
```

この`CustomMicrophone.RefreshMicrophoneDevices();`を差し込めばいいんですね。

# デモのスクリプトを改善
デモのスクリプトを改善して下記のようにしました。
改善部分を強調しています。
```C#:VoiceTest.cs
using FrostweepGames.Plugins.Native;
using FrostweepGames.VoicePro;
using UnityEngine;

public class VoiceTest : MonoBehaviour
{
    public Recorder recorder;

    public Listener listener;

    public bool isRecording;

    void Update()
    {
        //録音
        if (Input.GetKeyDown(KeyCode.R) && !isRecording)
        {
            StartRecord();
        }
        else if (Input.GetKeyUp(KeyCode.R) && isRecording)
        {
            StopRecord();
        }

        ///////////////////////////////////////////////////////
        //【リフレッシュ】
        if (Input.GetKey(KeyCode.F))
        {
            Debug.Log("Refresh");
            
            //マイクリストのリフレッシュ
            CustomMicrophone.RefreshMicrophoneDevices();

            //リストの中の最初の項目にマイクをセット
            recorder.SetMicrophone(CustomMicrophone.devices[0]);
        }
        ///////////////////////////////////////////////////////////////////
    }

    public void StartRecord()
    {
        if (CustomMicrophone.HasConnectedMicrophoneDevices())
        {
            recorder.SetMicrophone(CustomMicrophone.devices[0]);
            isRecording = recorder.StartRecord();

            Debug.Log("Record started: " + isRecording);
        }
        else
        {
            recorder.RefreshMicrophones();
        }
    }

    public void StopRecord()
    {
        isRecording = false;
        recorder.StopRecord();

        Debug.Log("Record ended");
    }
}
```

この例ではFキーを押すとリフレッシュされます。
マイクの許可をしたのち、Fキー連打してからだとRキー押すと話せるようになります。