Voice Live APIのUnity部品化
本記事は、前回の記事で紹介したMicrosoft Foundry Voice Live APIのUnity実装を、再利用可能なUPMパッケージとして部品化した UnityVoiceLiveAPI の設計と実装について解説します。
前回は単一のMonoBehaviourクラス(VoiceLiveAPISamples)としてVoice Live APIの接続からオーディオ処理までを実装しました。今回はそのコア機能を以下の観点で再設計しています。
- レイヤー分離 ― プロトコル処理とUnity固有処理の明確な分離
- 音声デバイスの抽象化 ― XRデバイスなど多様なマイクデバイスへの拡張を可能に
- WebRTCアバター連携 ― Unity WebRTCパッケージを活用したアバター映像のストリーミング
- ScriptableObjectベースの設定 ― Inspectorからの直感的な設定管理
1. パッケージ全体のアーキテクチャ
レイヤー構成
UnityVoiceLiveAPIは大まかな構造は以下の通りです。
Core Library(DLL) はVoice Live APIのWebSocketプロトコル処理を担当するプリコンパイル済みライブラリです。Unity側のコンポーネントはこのCoreを通じてAPIと通信します。Core Libraryは以前作成したVoice Live APIのサンプルで実装した部品になります。詳細は以下の記事の内容になります。
ディレクトリ構造
Assets/Reseul/VoiceLiveAPIForUnity/
├── Runtime/
│ ├── Assmblies/netstandard2.1/ # Core DLL + Azure依存DLL群
│ ├── Components/
│ │ └── UnityVoiceLiveClient.cs # メインコンポーネント
│ ├── Avatar/
│ │ └── UnityAvatarClient.cs # WebRTCアバター制御
│ ├── Audio/
│ │ ├── IAudioCapture.cs # 音声キャプチャインターフェース
│ │ ├── AudioCaptureBase.cs # 共通バッファリングロジック
│ │ ├── UnityAudioCapture.cs # Unity Microphone API実装
│ │ ├── IAudioConverter.cs # 音声変換インターフェース
│ │ ├── PCM16Converter.cs # PCM16変換実装
│ │ ├── AudioCaptureSettings.cs # キャプチャ設定基底
│ │ └── UnityAudioPlayback.cs # 応答音声再生
│ ├── Settings/
│ │ ├── FoundryConnectionSettings.cs # 接続設定
│ │ ├── VoiceLiveSessionSettings.cs # セッション設定
│ │ ├── VoiceSettings.cs # TTS音声設定
│ │ ├── AudioProcessingSettings.cs # オーディオ処理設定
│ │ ├── TurnDetectionSettings.cs # ターン検出設定
│ │ ├── AnimationSettings.cs # アバターアニメーション設定
│ │ └── VoiceLiveAvatarSettings.cs # アバター設定
│ ├── Prefabs/ # プレハブ
│ └── Com.Reseul.Azure.AI.VoiceLiveAPI.Unity.asmdef
├── Editor/ # エディタ拡張
└── Samples~/
├── AvatarSample/ # アバター音声対話サンプル
├── BasicVoiceChatSample/ # 基本音声チャットサンプル
└── TextInputSample/ # テキスト入力サンプル
2. 開発環境と導入方法
動作要件
| 項目 | バージョン・内容 |
|---|---|
| Unity | 6000.0 以降(Unity 6) |
| .NET | Standard 2.1 |
| WebRTCパッケージ | com.unity.webrtc 3.0.0+(アバター機能利用時のみ) |
| Azure | Microsoft Foundryリソース |
| ライセンス | Boost Software License 1.0 |
UPMパッケージの導入
Unity Package Managerから以下のいずれかの方法でインストールします。
Git URL経由(推奨):
- Unity Editorで Window > Package Manager を開く
- + ボタン > Add package from git URL を選択
- 以下のURLを入力:
https://github.com/TakahiroMiyaura/UnityVoiceLiveAPI.git#upm
特定バージョンを指定する場合:
https://github.com/TakahiroMiyaura/UnityVoiceLiveAPI.git#upm@1.0.0
WebRTCパッケージの導入(任意)
アバター機能を使用する場合はUnity WebRTCパッケージを追加します。
com.unity.webrtc 3.0.0
WebRTCパッケージは任意です。インストールされていない場合、アバター関連の機能は自動的に無効化されます。パッケージの有無は UNITY_WEBRTC_AVAILABLE プリプロセッサシンボルで判定しています。
依存パッケージ
パッケージインストール時に自動で解決されます。
| パッケージ | バージョン | 用途 |
|---|---|---|
com.unity.nuget.newtonsoft-json |
3.2.1+ | JSON処理 |
com.unity.webrtc |
3.0.0+(任意) | アバター映像ストリーミング |
3. UnityVoiceLiveClient ― コアコンポーネント
概要
UnityVoiceLiveClientはVoice Live APIとの接続・セッション管理・音声入出力を統括するメインコンポーネントです。
スレッドセーフなイベント処理
Voice Live APIとの通信はバックグラウンドスレッドで行われますが、Unityの多くのAPIはメインスレッドでしか呼び出せません。この辺りは対策済みなので、UnityEventの発火やAudioSourceの操作がメインスレッドで安全に行われます。
イベント一覧
UnityVoiceLiveClientは以下のUnityEventを公開しています。
| イベント | 引数 | タイミング |
|---|---|---|
OnConnected |
なし | WebSocket接続確立時 |
OnDisconnected |
なし | 接続切断時 |
OnSessionStarted |
なし | セッション開始時 |
OnSessionEnded |
なし | セッション終了時 |
OnTranscriptReceived |
string |
ユーザ音声の文字起こし完了時 |
OnResponseOutputItemDoneReceived |
string |
AI応答完了時 |
OnErrorOccurred |
string |
エラー発生時 |
主要プロパティ・メソッド
// 接続・切断
UnityVoiceLiveClient client = GetComponent<UnityVoiceLiveClient>();
client.Connect(); // WebSocket接続開始
client.Disconnect(); // 接続切断
// 音声録音の制御
client.StartRecording(); // マイクキャプチャ開始
client.StopRecording(); // キャプチャ停止
// テキスト入力(音声の代わりにテキストで会話)
client.SendMessage("こんにちは");
// 状態確認
bool connected = client.IsConnected;
bool recording = client.IsRecording;
bool avatarOn = client.IsAvatarEnabled;
接続設定(FoundryConnectionSettings)
接続情報はScriptableObjectで管理します。
作成方法: Project > Create > VoiceLive API > Foundry Connection Settings
| 設定項目 | 説明 |
|---|---|
| Endpoint | Microsoft Foundryのエンドポイント URL |
| Access Token | APIキーまたはBearerトークン |
| Connection Mode |
AIAgent(カスタムエージェント)または AIModel(GPT-4o等) |
セッション設定(VoiceLiveSessionSettings)
セッション動作の詳細をScriptableObjectで設定します。
作成方法: Project > Create > VoiceLive API > Voice Live Session Settings
| 設定グループ | 主な設定項目 |
|---|---|
| Voice | TTS音声名(例:en-US-Aria:DragonHDLatestNeural)、音声温度 |
| Audio Processing | サンプリングレート(デフォルト24kHz)、入出力処理オプション |
| Turn Detection | VADタイプ(azure_semantic_vad等)、閾値、無音検出時間 |
| Avatar | アバター設定(有効時のみ) |
4. オーディオシステムの設計
音声キャプチャの抽象化
前回のサンプルではAudioSource.clip.GetData()で直接音声データを取得していましたが、本パッケージではデバイスの差異を吸収するための抽象レイヤーを設けています。
IAudioCapture はマイクデバイスに依存しないインターフェースです。標準ではUnityAudioCapture(Unity Microphone API利用)が提供されていますが、IAudioCaptureを実装することでMiRZAやMeta QuestなどのXRデバイス固有のマイクAPIにも対応できます。
IAudioConverter は音声フォーマット変換の抽象化です。Voice Live APIが要求するPCM16形式への変換をPCM16Converterが担当しますが、将来的に異なるフォーマットが必要になった場合にも差し替え可能です。
音声キャプチャ設定(AudioCaptureSettings)
音声キャプチャの設定もScriptableObjectで管理します。
作成方法: Project > Create > VoiceLive API > Audio Capture > Unity Microphone
デバイス名やサンプリングレートをInspectorから設定可能です。
音声再生
AI応答の音声データはCore LibraryからPCM16(Base64エンコード)として受信され、UnityAudioPlaybackがデコード・バッファリング・AudioSource経由の再生を行います。前回のサンプルではOnAudioFilterReadで直接キューからデキューしていましたが、本パッケージではこの処理をコンポーネントとして分離し、再利用性を高めています。
5. UnityAvatarClient ― WebRTCアバター連携
概要
UnityAvatarClientは、Unity WebRTCパッケージを使ってVoice Live APIのアバター映像をストリーミング表示するコンポーネントです。
UnityAvatarClientはcom.unity.webrtc 3.0.0以上がインストールされている場合のみ有効です。アセンブリ定義のversionDefinesにより、UNITY_WEBRTC_AVAILABLEプリプロセッサシンボルが自動的に定義されます。
WebRTC接続フロー
Inspector設定
| 設定項目 | 説明 |
|---|---|
| RawImage | アバター映像を表示するUI要素 |
| AudioSource | アバター音声を再生するAudioSource |
| Enable Debug Logging | デバッグログの有効化 |
アバターアニメーション
Voice Live APIはアバターのリップシンクやフェイシャルアニメーション用のデータも提供します。設定でアニメーション出力タイプを選択できます。
| 出力タイプ | 説明 |
|---|---|
viseme_id |
Viseme ID(口形素)によるリップシンク |
blend_shapes |
BlendShapeターゲットによるフェイシャルアニメーション |
アバター設定(VoiceLiveAvatarSettings)
VoiceLiveSessionSettingsの一部としてアバター関連の設定を行います。AnimationSettings内でViseme IDやBlendShapesの有効化を設定できます。
6. 利用方法(Getting Started)
基本的な音声チャット
最もシンプルな構成で音声対話を実現する手順です。
認証について
Microsoft Foundryを利用する場合はEntra IDによる認証を通じたトークンによる活用が推奨されています。以降の作業を行う際には、あらかじめMicrosoft Foundryへのリソースアクセス可能なユーザによるアクセストークンを用意する必要があります。Unity Enditor上で簡単に検証したい場合は以下のコマンドでトークンを生成しFoundryConnectionSettingsに設定することで試すことが可能です。
az account get-access-token --resource https://ai.azure.com --subscription "<subscription ID or name>"
実際にUnityアプリとして構築する際には認証の仕組みを導入する必要があります。これについては別記事で紹介したUnity上でEntra ID認証をおこなうためのUnityパッケージも作成しているので参考にして下さい。
Step 1: 設定アセットの作成
-
FoundryConnectionSettings を作成(Create > VoiceLive API > Foundry Connection Settings)
- Endpoint、APIキー、接続モードを設定
-
VoiceLiveSessionSettings を作成(Create > VoiceLive API > Voice Live Session Settings)
- 音声設定、ターン検出を設定
-
AudioCaptureSettings を作成(Create > VoiceLive API > Audio Capture > Unity Microphone)
- マイクデバイスを指定
Step 2: シーンの構成
- 空のGameObjectを作成(例:
VoiceLiveSystem) -
UnityVoiceLiveClientコンポーネントを追加 - Inspectorで設定アセットをアサイン:
- Connection Settings → Step 1で作成したFoundryConnectionSettings
- Session Settings → Step 1で作成したVoiceLiveSessionSettings
- Audio Capture Settings → Step 1で作成したAudioCaptureSettings
- AudioSource → 応答音声再生用のAudioSourceをアサイン
Step 3: イベントハンドリング
using Com.Reseul.Azure.AI.VoiceLiveAPI.Unity.Components;
using UnityEngine;
public class VoiceChatExample : MonoBehaviour
{
[SerializeField] private UnityVoiceLiveClient voiceLiveClient;
void Start()
{
// イベント登録
voiceLiveClient.OnConnected.AddListener(OnConnected);
voiceLiveClient.OnTranscriptReceived.AddListener(OnTranscript);
voiceLiveClient.OnResponseOutputItemDoneReceived.AddListener(OnResponse);
voiceLiveClient.OnErrorOccurred.AddListener(OnError);
// 接続開始
voiceLiveClient.Connect();
}
private void OnConnected()
{
Debug.Log("Voice Live APIに接続しました");
// マイク入力を開始
voiceLiveClient.StartRecording();
}
private void OnTranscript(string transcript)
{
Debug.Log($"ユーザ発話: {transcript}");
}
private void OnResponse(string response)
{
Debug.Log($"AI応答: {response}");
}
private void OnError(string error)
{
Debug.LogError($"エラー: {error}");
}
void OnDestroy()
{
voiceLiveClient.Disconnect();
}
}
アバター付き音声チャット
アバターを表示しながら音声対話を行う構成です。
追加手順
-
com.unity.webrtc3.0.0+ をPackage Managerからインストール - シーンにCanvasとRawImageを追加(アバター映像表示用)
- アバター音声用のAudioSourceを追加
-
UnityAvatarClientコンポーネントを追加し、RawImageとAudioSourceをアサイン -
UnityVoiceLiveClientのAvatar ClientフィールドにUnityAvatarClientをアサイン - VoiceLiveSessionSettingsでアバター設定を有効化
using Com.Reseul.Azure.AI.VoiceLiveAPI.Unity.Components;
using Com.Reseul.Azure.AI.VoiceLiveAPI.Unity.Avatar;
using UnityEngine;
public class AvatarChatExample : MonoBehaviour
{
[SerializeField] private UnityVoiceLiveClient voiceLiveClient;
[SerializeField] private UnityAvatarClient avatarClient;
void Start()
{
voiceLiveClient.OnConnected.AddListener(() =>
{
Debug.Log("接続完了");
voiceLiveClient.StartRecording();
});
avatarClient.OnConnectionEstablished.AddListener(() =>
{
Debug.Log("アバター映像ストリーミング開始");
});
voiceLiveClient.Connect();
}
void OnDestroy()
{
voiceLiveClient.Disconnect();
}
}
テキスト入力での対話
音声の代わりにテキストで会話する場合は SendMessage() を使います。
// テキストで会話
voiceLiveClient.SendMessage("今日の天気を教えて");
サンプルシーン
パッケージには3つのサンプルが含まれています。Package ManagerのSamplesタブからインポートできます。
| サンプル | 内容 |
|---|---|
| BasicVoiceChatSample | マイク入力による音声対話の最小構成 |
| AvatarSample | WebRTCアバター表示付きの音声対話 |
| TextInputSample | テキスト入力ベースの対話 |
まとめと今後の展望
本記事では、Voice Live APIのUnity向けUPMパッケージ UnityVoiceLiveAPI の設計と実装について解説しました。
様々な生成AI技術を利用する上で管理されたエージェントを活場合Micosoft Foundryは1つの選択肢になると思います。
Micosoft Foundry自体は気軽にエージェントを使うというよりは、業務やAzureのリソース等様々な情報を活用も可能なエンタープライズグレードなプラットフォームではあるので様々なUI、UXで活用できることは重要な要素になりうると思います。
今後のさまざまなエンハンスがあると思うので引続きチェックしていきたいと思います。