탐색으로 건너뛰기

Unity SDK

ElevenAgents SDK: Unity 게임에 맞춤형 인터랙티브 음성 에이전트를 배포하세요.

ElevenAgents의 작동 방식은 ElevenAgents 개요를 참조하세요.

ElevenAgents Unity SDK는 Unity 씬을 ElevenLabs 에이전트에 연결합니다. 플레이어의 마이크를 캡처하고, 에이전트의 음성을 AudioSource를 통해 다시 스트리밍하며, Editor, 데스크톱 독립형 플레이어 및 WebGL 빌드에서 동일하게 작동하는 단일 Conversation API를 통해 세션을 제공합니다.

요구 사항

  • Unity 6.3 LTS (6000.3.0f1) 이상. SDK는 Unity 6.3에서 도입된 스크립터블 오디오 API를 사용합니다.
  • Api Compatibility Level을 Unity 2023.1 이상 기본값인 .NET Standard 2.1로 설정합니다.
  • ElevenLabs 계정과 에이전트. 대시보드에서 생성하거나 빠른 시작을 따르세요.

플랫폼 지원

대상전송 방식상태
Editor(Play Mode), 데스크톱 독립형(macOS, Windows, Linux)네이티브 WebSocket지원됨
WebGLJS 브리지를 통한 @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가 의존성인 Input System 및 Newtonsoft Json과 함께 ElevenAgents 패키지(io.elevenlabs.agents)를 설치합니다.

패키지에는 두 개의 샘플이 포함되어 있습니다. Package Manager > ElevenAgents > Samples에서 가져오세요. QuickStart는 실시간 트랜스크립트를 렌더링하는 단일 MonoBehaviour입니다. GettingStarted는 공간 오디오와 동적 변수가 포함된 다가가서 대화하는 씬입니다. 단계별 안내는 시작하기 가이드를 참조하세요.

빠른 시작

이 섹션에서는 빈 씬에 음성 에이전트를 추가합니다. Play Mode에 진입하면 에이전트가 대화를 시작하고, 종료하면 세션도 끝납니다.

1

공개 에이전트 만들기

ElevenLabs 대시보드에서 에이전트를 만드세요. 에이전트의 Security 설정에서 게임이 에이전트 ID만으로 연결할 수 있도록 Authentication을 끄세요. 에이전트 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 컴포넌트를 추가한 다음, Agent Id 필드에 에이전트 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의 볼륨, 위치 및 공간 설정을 미러링합니다. 따라서 WebGL에서 AudioSource.GetOutputData와 OnAudioFilterRead는 무음을 반환합니다. 대신 GetOutputVolume()과 GetOutputByteFrequencyData()를 사용하세요.

활성 빌드 대상이 WebGL인 동안에는 Editor의 Play Mode가 아직 지원되지 않습니다. Editor에서 테스트하려면 데스크톱 빌드 대상으로 전환하세요.

전체 WebGL 호환성 매트릭스는 COMPATIBILITY.md를 참조하세요.

문제 해결

  • StartSessionAsync가 ArgumentException을 발생시킵니다. AgentId, SignedUrl, ConversationToken 중 정확히 하나를 설정하세요.
  • 유효한 에이전트 ID로 세션 연결에 실패합니다. 에이전트에 인증이 필요합니다. 인증을 끄거나 서명된 URL로 연결하세요.
  • 재정의가 적용되지 않습니다. 에이전트의 Security 설정에서 해당 재정의를 활성화하세요.
  • 플레이어가 WebGL에서 아무 소리도 듣지 못합니다. 브라우저는 플레이어가 페이지와 상호작용할 때까지 오디오를 일시 중지 상태로 유지합니다. 클릭 또는 키 입력 후 세션을 시작하세요.
  • WebGL에서 마이크를 사용할 수 없습니다. 브라우저는 HTTPS 또는 localhost에서 제공되는 페이지에만 마이크 액세스를 허용합니다.

버그 신고 및 기능 요청은 GitHub에서 하세요.