> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Unity SDK

> **Info**
>
> ElevenAgentsの仕組みについては、[ElevenAgentsの概要](/docs/ja/eleven-agents/overview)を参照してください。

[ElevenAgents Unity SDK](https://github.com/elevenlabs/unity)は、UnityシーンをElevenLabsエージェントに接続します。プレイヤーのマイクをキャプチャし、エージェントの音声を`AudioSource`経由でストリーミングし、Editor、デスクトップスタンドアロンプレイヤー、WebGLビルドで同じように動作する単一の`Conversation` APIを通じてセッションを公開します。

## 要件

* Unity 6.3 LTS（`6000.3.0f1`）以降。SDKはUnity 6.3で導入されたスクリプタブルオーディオAPIを使用します。
* **Api Compatibility Level**を **.NET Standard 2.1**に設定。これはUnity 2023.1以降のデフォルトです。
* ElevenLabsアカウントとエージェント。[ダッシュボード](https://elevenlabs.io/app/agents)で作成するか、[クイックスタート](/docs/ja/eleven-agents/quickstart)に従ってください。

### プラットフォーム対応

| ターゲット                                                | トランスポート                       | ステータス                    |
| ---------------------------------------------------- | ----------------------------- | ------------------------ |
| Editor（Play Mode）、デスクトップスタンドアロン（macOS、Windows、Linux） | ネイティブWebSocket                | 対応済み                     |
| WebGL                                                | JSブリッジ経由の`@elevenlabs/client` | 対応済み（WebSocketおよびWebRTC） |
| iOS、Android、XR                                       | ネイティブWebSocket                | 未テスト                     |

SDKは、アクティブなビルドターゲットに応じてトランスポートを自動選択します。WebRTCはWebGLでのみ利用できます。その他すべてのターゲットでは、`ConnectionType.WebRTC`は`NotSupportedException`をスローします。

> **Note**
>
> SDKはマイク権限をリクエストしません。iOSおよびAndroidでは、セッションを開始する前に自分でリクエストしてください。

## インストール

Unityで**Window** ＞ **Package Manager**を開き、**+** ＞ **Install package from git URL**を選択して、リポジトリURLを貼り付けます。

```text
https://github.com/elevenlabs/unity.git
```

Package Managerは、依存関係のInput SystemおよびNewtonsoft Jsonとともに、パッケージを**ElevenAgents**（`io.elevenlabs.agents`）としてインストールします。

> **Tip**
>
> パッケージには2つのサンプルが含まれています。**Package Manager** ＞ **ElevenAgents** ＞ **Samples**からインポートしてください。**QuickStart**は、ライブ文字起こしを表示する単一のMonoBehaviourです。**GettingStarted**は、空間オーディオと動的変数を備えた、近づいて話しかけるためのシーンです。手順ごとのガイドは、[Getting started walkthrough](https://github.com/elevenlabs/unity/blob/main/Docs~/GETTING_STARTED.md)を参照してください。

## クイックスタート

このセクションでは、空のシーンに音声エージェントを追加します。Play Modeに入るとエージェントが話し始め、Play Modeを終了するとセッションも終了します。

#### パブリックエージェントを作成する

[ElevenLabsダッシュボード](https://elevenlabs.io/app/agents)でエージェントを作成します。エージェントの**Security**設定で**Authentication**をオフにすると、ゲームはエージェントIDだけで接続できます。エージェントIDをコピーしてください。

認証が必要なエージェントについては、[パブリックエージェントとプライベートエージェント](#public-and-private-agents)を参照してください。

#### SDKをインストールする

[インストール](#installation)で説明したとおりに、git URLからパッケージをインストールします。

#### 会話スクリプトを追加する

`Assets/Scripts/AgentConversation.cs`を作成します。

**`AgentConversation.cs`**

```csharp title="AgentConversation.cs"
using System;
using ElevenLabs.Agents;
using ElevenLabs.Protocol;
using UnityEngine;

public sealed class AgentConversation : MonoBehaviour
{
    [SerializeField]
    private string agentId = "agent_7101k5zvyjhmfg983brhmhkd98n6";

    private Conversation conversation;

    private async void Start()
    {
        try
        {
            conversation = await Conversation.StartSessionAsync(
                new ConversationOptions { AgentId = agentId }
            );
        }
        catch (Exception ex)
        {
            Debug.LogError($"Failed to start session: {ex.Message}");
            return;
        }

        Debug.Log($"Connected: {conversation.ConversationId}");

        conversation.UserTranscriptReceived += OnUserTranscript;
        conversation.AgentResponded += OnAgentResponse;
        conversation.ErrorOccurred += message => Debug.LogError(message);
        conversation.Disconnected += details => Debug.Log($"Disconnected: {details.Reason}");
    }

    private void OnUserTranscript(UserTranscriptArgs args) =>
        Debug.Log($"User: {args.UserTranscript}");

    private void OnAgentResponse(AgentResponseArgs args) =>
        Debug.Log($"Agent: {args.AgentResponse}");

    private void OnDestroy()
    {
        _ = conversation?.EndSession();
    }
}
```

`Conversation.StartSessionAsync`は、接続が開き、オーディオデバイスの準備が整うと返ります。`EndSession`はべき等であるため、セッションがすでに終了していても`OnDestroy`から安全に呼び出せます。

#### シーンを実行する

空のGameObjectを作成し、`AgentConversation`コンポーネントを追加して、**Agent Id**フィールドにエージェントIDを貼り付けます。Play Modeに入り、OSから求められた場合はマイクアクセスを許可してください。エージェントが最初のメッセージを話し、文字起こしがConsoleに表示されます。

## パブリックエージェントとプライベートエージェント

#### パブリックエージェント

エージェントIDを直接渡します。IDを知っている人は誰でも、エージェントとの会話を開始できます。

```csharp
var conversation = await Conversation.StartSessionAsync(
    new ConversationOptions { AgentId = "agent_7101k5zvyjhmfg983brhmhkd98n6" }
);
```

#### プライベートエージェント

認証を有効にしたエージェントには、独自のサーバーが発行する短期間有効な認証情報が必要です。バックエンドから[署名付きURL](/docs/ja/eleven-agents/customization/authentication)をリクエストし、`SignedUrl`として渡します。

```csharp
using UnityEngine.Networking;

private static async Awaitable<string> FetchSignedUrlAsync()
{
    using var request = UnityWebRequest.Get("https://api.example-game.com/agent/signed-url");
    await request.SendWebRequest();
    if (request.result != UnityWebRequest.Result.Success)
        throw new InvalidOperationException(request.error);
    return request.downloadHandler.text;
}

var conversation = await Conversation.StartSessionAsync(
    new ConversationOptions { SignedUrl = await FetchSignedUrlAsync() }
);
```

WebGL上のWebRTCセッションでは、会話トークンを`ConversationToken`として渡し、`ConnectionType = ConnectionType.WebRTC`を設定します。

> **Warning**
>
> ElevenLabs APIキーをゲームビルドに絶対に含めないでください。署名付きURLと会話トークンは、自分で管理するサーバー上で生成してください。

`AgentId`、`SignedUrl`、`ConversationToken`のいずれか1つだけを設定してください。独自システム内のプレイヤーと会話を関連付けるには、`UserId`を設定します。

## 空間オーディオ

デフォルトでは、SDKが作成する非表示の`AudioSource`を通じてエージェントの音声を再生します。シーン内に音声を配置するには、独自の`AudioSource`を`OutputAudioSource`として渡します。

```csharp
[SerializeField]
private AudioSource voiceSource; // Spatial Blend = 1 for 3D audio

var conversation = await Conversation.StartSessionAsync(
    new ConversationOptions
    {
        AgentId = "agent_7101k5zvyjhmfg983brhmhkd98n6",
        OutputAudioSource = voiceSource,
    }
);
```

SDKは、ソースの空間ブレンド、ロールオフ、ミキサールーティング、位置を維持します。セッション終了時には、ソースのクリップ、ループ、音量設定を復元します。

口のアニメーションなど、エージェントの音声で視覚効果を動かすには、毎フレーム`conversation.GetOutputVolume()`を読み取ります。すべてのプラットフォームで、0から1までの値を返します。

## パーソナライズ

[動的変数](/docs/ja/eleven-agents/customization/personalization/dynamic-variables)を使用すると、エージェントのプロンプトと最初のメッセージ内のプレースホルダーを入力できます。また、[オーバーライド](/docs/ja/eleven-agents/customization/personalization/overrides)を使用すると、1つのセッションについてエージェント設定の一部を置き換えられます。

```csharp
using System.Collections.Generic;
using ElevenLabs.Protocol;

var options = new ConversationOptions
{
    AgentId = "agent_7101k5zvyjhmfg983brhmhkd98n6",
    DynamicVariables = new Dictionary<string, object>
    {
        ["player_name"] = "Ada",
        ["quest_stage"] = 3,
    },
    Overrides = new ConversationConfigOverride
    {
        Agent = new ConversationConfigOverrideAgent
        {
            FirstMessage = "Welcome back, {{player_name}}.",
        },
        Tts = new ConversationConfigOverrideTts { VoiceId = "JBFqnCBsd6RMkjVDRZzb" },
    },
};
```

動的変数の値には、文字列、数値、またはブール値を使用する必要があります。サーバーが受け入れる前に、各オーバーライドをエージェントの**Security**設定で有効にする必要があります。

## クライアントツール

[クライアントツール](/docs/ja/eleven-agents/customization/tools/client-tools)を使うと、エージェントはゲーム内でアクションをトリガーできます。エージェント設定でツールを定義してから、同じ名前のハンドラーを登録します。

```csharp
using Newtonsoft.Json;

public sealed class OpenDoorParams
{
    [JsonProperty("door_id")]
    public string DoorId { get; set; }
}

conversation.RegisterTool<OpenDoorParams, string>("open_door", parameters =>
{
    DoorRegistry.Open(parameters.DoorId);
    return $"Door {parameters.DoorId} is open.";
});
```

SDKはNewtonsoft Jsonを使用してツールパラメータを`TParams`にデシリアライズするため、パラメータ名がプロパティ名と異なる場合は`[JsonProperty]`を使用してください。戻り値はツール結果としてシリアライズされます。非同期ハンドラーには`Awaitable<TResult>`を返します。特定の失敗をエージェントに報告するには、`errorType`を指定して`ClientToolException`をスローします。その他の例外は一般的なエラーとして報告されます。

登録済みハンドラーのないツール呼び出しでは、`ErrorOccurred`が発生します。`UnhandledClientToolCall`を購読している場合は、代わりにそちらが発生します。

## イベント

`StartSessionAsync`が返す`Conversation`のイベントを購読します。SDKはUnityのメインスレッドでこれらを発生させます。

| イベント                      | ペイロード                  | 説明                                                    |
| ------------------------- | ---------------------- | ----------------------------------------------------- |
| `Disconnected`            | `DisconnectionDetails` | セッションが終了しました。`Reason`は`User`、`Agent`、または`Error`です。    |
| `ErrorOccurred`           | `string`               | セッション開始後にエラーが発生しました。                                  |
| `StatusChanged`           | `Status`               | 接続ステータスが変更されました。                                      |
| `ModeChanged`             | `Mode`                 | エージェントが`Speaking`と`Listening`を切り替えました。                |
| `UserTranscriptReceived`  | `UserTranscriptArgs`   | プレイヤーの発話の確定済み文字起こし。                                   |
| `AgentResponded`          | `AgentResponseArgs`    | エージェント応答のテキスト。                                        |
| `Interrupted`             | `InterruptionArgs`     | プレイヤーがエージェントを中断しました。                                  |
| `AgentToolRequested`      | `AgentToolRequestArgs` | エージェントがツール呼び出しを開始しました。完了時に`AgentToolResponded`が発生します。 |
| `UnhandledClientToolCall` | `ClientToolCallArgs`   | エージェントが、登録済みハンドラーのないクライアントツールを呼び出しました。                |
| `CanSendFeedbackChanged`  | `bool`                 | 最新のエージェント応答に対するフィードバックが利用可能または利用不可になりました。             |

`Connected`イベントは`StartSessionAsync`が返る前に発生するため、呼び出しの完了後に`ConversationId`と`Status`を直接読み取ってください。[パッケージの変更履歴](https://github.com/elevenlabs/unity/blob/main/CHANGELOG.md)には、すべてのイベント一覧が記載されています。

## メソッド

| メソッド                                                          | 説明                                              |
| ------------------------------------------------------------- | ----------------------------------------------- |
| `EndSession()`                                                | 接続を閉じ、オーディオデバイスを解放します。                          |
| `SendUserMessage(string text)`                                | プレイヤーが発話したかのようにテキストメッセージを送信します。                 |
| `SendContextualUpdate(string text)`                           | 会話を中断せずにゲームの状態をエージェントと共有します。                    |
| `SendUserActivity()`                                          | プレイヤーがアクティブであることを通知し、エージェントがターンを維持します。          |
| `SendFeedback(bool like)`                                     | `CanSendFeedback`が`true`の場合に、最新のエージェント応答を評価します。 |
| `SetMicMuted(bool isMuted)`                                   | マイクをミュートまたはミュート解除します。                           |
| `SetVolume(float volume)`                                     | エージェントの再生音量を0から1の範囲で設定します。                      |
| `GetInputVolume()`, `GetOutputVolume()`                       | 現在のマイクまたはエージェントのオーディオレベルを0から1の範囲で取得します。         |
| `GetInputByteFrequencyData()`, `GetOutputByteFrequencyData()` | オーディオビジュアライザー用の周波数データをバイトバッファに入力します。            |
| `UploadFileAsync()`, `SendMultimodalMessage()`                | ファイルをアップロードし、ユーザーメッセージに添付します。                   |
| `ChangeInputDevice()`, `ChangeOutputDevice()`                 | セッション中にマイクまたは出力デバイスを切り替えます。                     |

たとえば、プレイヤーが新しいエリアに入ったとき、現在地をエージェントに送信します。

```csharp
conversation.SendContextualUpdate("The player entered the abandoned lighthouse.");
```

## WebGLビルド

WebGLビルドには、追加のPlayer Settingが1つ必要です。**Player Settings** ＞ **WebGL** ＞ **Publishing Settings**で、**Use WebAssembly.Table**をオンにします。この設定がオフの場合、SDKは手順を表示してビルドを失敗させます。

UnityにはWebGL用のスクリプタブルオーディオパイプラインがないため、SDKはブラウザのWeb Audio APIを通じてエージェントの音声を再生し、`OutputAudioSource`の音量、位置、空間設定を反映します。そのため、WebGLでは`AudioSource.GetOutputData`と`OnAudioFilterRead`は無音を返します。代わりに`GetOutputVolume()`と`GetOutputByteFrequencyData()`を使用してください。

> **Note**
>
> アクティブなビルドターゲットがWebGLの場合、EditorのPlay Modeはまだサポートされていません。Editorでテストするには、デスクトップビルドターゲットに切り替えてください。

WebGLの完全な互換性マトリクスについては、[`COMPATIBILITY.md`](https://github.com/elevenlabs/unity/blob/main/COMPATIBILITY.md)を参照してください。

## トラブルシューティング

* **`StartSessionAsync`が`ArgumentException`をスローする。** `AgentId`、`SignedUrl`、`ConversationToken`のいずれか1つだけを設定してください。
* **有効なエージェントIDでセッション接続に失敗する。** エージェントに認証が必要です。認証をオフにするか、署名付きURLで接続してください。
* **オーバーライドが反映されない。** エージェントの**Security**設定で対応するオーバーライドを有効にしてください。
* **WebGLでプレイヤーに音が聞こえない。** ブラウザは、プレイヤーがページを操作するまでオーディオを停止したままにします。クリックまたはキー操作の後にセッションを開始してください。
* **WebGLでマイクを利用できない。** ブラウザは、HTTPSまたは`localhost`から配信されるページにのみマイクアクセスを許可します。

バグの報告や機能リクエストは、[GitHub](https://github.com/elevenlabs/unity/issues)で受け付けています。