跳到导航

Unity SDK

ElevenAgents SDK:在 Unity 游戏中部署定制化交互式语音智能体。

有关 ElevenAgents 工作原理的说明,请参阅 ElevenAgents 概览。

ElevenAgents Unity SDK 可将 Unity 场景连接到 ElevenLabs 智能体。它会采集玩家麦克风输入,通过 AudioSource 流式播放智能体语音,并通过统一的 Conversation API 暴露会话;该 API 在编辑器、桌面独立播放器和 WebGL 构建中行为一致。

要求

  • Unity 6.3 LTS(6000.3.0f1)或更高版本。SDK 使用了 Unity 6.3 引入的可脚本化音频 API。
  • 将 Api Compatibility Level 设为 .NET Standard 2.1,这是 Unity 2023.1 及更高版本的默认设置。
  • ElevenLabs 账户和智能体。可在控制台创建,或按照快速入门操作。

平台支持

目标传输方式状态
编辑器(Play Mode)、桌面独立版(macOS、Windows、Linux)原生 WebSocket支持
WebGL通过 JS 桥接使用 @elevenlabs/client支持(WebSocket 和 WebRTC)
iOS、Android、XR原生 WebSocket未测试

SDK 会自动为当前构建目标选择传输方式。WebRTC 仅在 WebGL 上可用;在其他所有目标上,ConnectionType.WebRTC 会抛出 NotSupportedException。

SDK 不会请求麦克风权限。在 iOS 和 Android 上,请在启动会话前自行请求权限。

安装

在 Unity 中,打开 Window > Package Manager,选择 + > Install package from git URL,然后粘贴仓库 URL:

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

Package Manager 会安装 ElevenAgents(io.elevenlabs.agents)包及其依赖项:Input System 和 Newtonsoft Json。

该包附带两个示例。从 Package Manager > ElevenAgents > Samples 导入。QuickStart 是一个用于渲染实时转写的单一 MonoBehaviour。 GettingStarted 是一个支持空间音频和动态变量的即走即聊场景。有关分步指南,请参阅 入门 演练。

快速入门

本节将语音智能体添加到空场景中。进入 Play Mode 时智能体会开始说话,退出时会话结束。

1

创建公开智能体

在 ElevenLabs 控制台中创建智能体。在智能体的 Security 设置中关闭 Authentication,这样游戏仅凭智能体 ID 即可连接。复制智能体 ID。

对于需要身份验证的智能体,请参阅公开和私有智能体。

2

安装 SDK

按照安装中的说明,通过 git URL 安装该包。

3

添加对话脚本

创建 Assets/Scripts/AgentConversation.cs:

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 调用它也是安全的。

4

运行场景

创建一个空 GameObject,添加 AgentConversation 组件,并将智能体 ID 粘贴到 Agent Id 字段。进入 Play Mode,并在操作系统提示时允许麦克风访问。智能体会说出第一条消息,转写内容将显示在 Console 中。

公开和私有智能体

直接传入智能体 ID。任何拥有该 ID 的人都可以与智能体开始对话。

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

AgentId、SignedUrl 或 ConversationToken 必须且只能设置一个。设置 UserId 可在自己的系统中将对话关联到玩家。

空间音频

默认情况下,SDK 会通过其创建的隐藏 AudioSource 播放智能体语音。要将语音放置在场景中,请将自己的 AudioSource 作为 OutputAudioSource 传入:

[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 之间的值。

个性化

使用动态变量填充智能体提示词和首条消息中的占位符,并使用覆盖替换单次会话的部分智能体配置:

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 设置中启用相应覆盖。

客户端工具

客户端工具可让智能体在游戏中触发操作。在智能体设置中定义工具,然后注册同名处理程序:

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 主线程上触发这些事件。

事件负载说明
DisconnectedDisconnectionDetails会话已结束。Reason 为 User、Agent 或 Error。
ErrorOccurredstring会话启动后发生错误。
StatusChangedStatus连接状态已更改。
ModeChangedMode智能体在 Speaking 和 Listening 之间切换。
UserTranscriptReceivedUserTranscriptArgs玩家语音的最终转写。
AgentRespondedAgentResponseArgs智能体回复的文本。
InterruptedInterruptionArgs玩家打断了智能体。
AgentToolRequestedAgentToolRequestArgs智能体开始调用工具。完成时触发 AgentToolResponded。
UnhandledClientToolCallClientToolCallArgs智能体调用了没有已注册处理程序的客户端工具。
CanSendFeedbackChangedbool最新智能体回复的反馈变为可用或不可用。

Connected 事件会在 StartSessionAsync 返回前触发,因此调用完成后可直接读取 ConversationId 和 Status。包更新日志列出了完整事件列表。

方法

方法说明
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()在会话期间切换麦克风或输出设备。

例如,当玩家进入新区域时,将当前位置发送给智能体:

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

WebGL 构建

WebGL 构建需要额外配置一项 Player Setting。在 Player Settings > WebGL > Publishing Settings 中,开启 Use WebAssembly.Table。如果此设置关闭,SDK 会使构建失败并提供操作说明。

Unity 在 WebGL 上没有可脚本化音频管线,因此 SDK 会通过浏览器的 Web Audio API 播放智能体语音,并镜像 OutputAudioSource 的音量、位置和空间设置。因此,AudioSource.GetOutputData 和 OnAudioFilterRead 在 WebGL 上会返回静音。请改用 GetOutputVolume() 和 GetOutputByteFrequencyData()。

当当前构建目标为 WebGL 时,编辑器中的 Play Mode 尚不受支持。请切换到桌面构建目标以在编辑器中测试。

完整的 WebGL 兼容性矩阵请参阅 COMPATIBILITY.md。

故障排除

  • StartSessionAsync 抛出 ArgumentException。 AgentId、SignedUrl 或 ConversationToken 必须且只能设置一个。
  • 使用有效智能体 ID 时会话无法连接。 该智能体需要身份验证。请关闭身份验证,或使用签名 URL 连接。
  • 覆盖未生效。 在智能体的 Security 设置中启用对应覆盖。
  • 玩家在 WebGL 上听不到声音。 浏览器会暂停音频,直到玩家与页面交互。请在点击或按键后启动会话。
  • WebGL 上的麦克风不可用。 浏览器仅向通过 HTTPS 或 localhost 提供的页面授予麦克风访问权限。

请在 GitHub 报告错误和提出功能请求。