본문 바로가기
Programming/AI

Unity에서 OpenAI API로 TTS 붙이기

by Dev_카페인 2026. 3. 26.
반응형

Unity에서 OpenAI API로 TTS 붙이기

텍스트를 음성으로 바꾸고 AudioSource로 재생해본 기록

앞선 글들에서는 Unity에서 OpenAI API를 이용해 텍스트를 만들고, 이미지를 생성하고, 기존 이미지를 편집하는 과정까지 정리했다. 이번에는 그 흐름을 오디오 쪽으로 확장해봤다. 목표는 단순했다. 텍스트를 입력으로 주고, 그 결과를 실제 음성으로 만들어 Unity 안에서 재생하는 것이었다. 문서 기록 기준으로 이 파트는 OpenAI API TTS Generator로 정리되어 있고, 내용도 비교적 명확하다. 오디오 기능 개요를 먼저 짚고, 그 다음 TTS를 어떻게 Unity 씬 안에 붙였는지 설명하는 구조다.

 

이번 글은 음성 입력을 받아 다시 텍스트로 바꾸는 STT 파트는 아직 다루지 않는다. 이번 4편은 어디까지나 텍스트 → 음성 출력에 집중한다. 즉, 지금까지 만든 텍스트 생성 결과를 실제 말소리로 바꾸는 단계라고 보면 된다. 이 지점이 중요한 이유는, 여기까지 오면 단순히 Console에 문자열을 찍는 수준을 넘어서 Unity 안에서 실제로 말하는 AI 같은 체감을 만들 수 있기 때문이다.


1. 왜 TTS를 따로 정리해야 하는가

처음 보기에는 TTS도 텍스트 생성의 연장처럼 보일 수 있다. 실제로 문서에도 “TTS를 활용하는 코드는 TextGenerator랑 비슷하다”고 적혀 있다. 하지만 구현 목적은 꽤 다르다. 텍스트 생성은 결과 문자열만 받으면 끝이지만, TTS는 오디오 데이터 수신, AudioClip 변환, AudioSource 재생까지 포함된다. 즉, API 호출 자체보다도 Unity 안에서 이 결과를 어떻게 처리하느냐가 더 큰 비중을 차지한다.

 

그리고 이 파트는 이후 STT나 도슨트 구조로 이어지기 때문에 별도 글로 빼는 게 맞다. 텍스트 생성과 바로 묶어버리면 “모델이 답했다”에서 끝나지만, TTS가 들어가는 순간부터는 “모델이 실제로 말한다”는 흐름으로 넘어간다. 문서 수정 이력에서도 TTS(Text To Speech) Generator 기능 추가가 이미지 편집 이후 별도 단계로 들어가 있다. 이건 기능적으로도 독립 파트로 보는 게 맞다는 뜻이다.


2. OpenAI API 오디오 기능을 어떻게 이해했는가

문서에서는 TTS 설명에 들어가기 전에 OpenAI API의 오디오 기능 개요를 먼저 짚고 있다. 핵심은 OpenAI API가 오디오를 입력으로도, 출력으로도, 혹은 둘 다를 통해서도 처리할 수 있다는 점이다. 그리고 실시간 대화가 가능한 STS(Speech To Speech)도 제공한다고 정리한다. 다만 문서에서는 여기서 바로 STS로 가지 않고, 보다 세밀하고 예측 가능한 제어를 위해서는 음성 → 텍스트 → LLM → 텍스트 → 음성 구조가 더 낫다고 설명한다. 이유는 간단하다. 음성 응답을 직접 생성하는 구조는 자연스럽긴 하지만, 모델이 정확히 무슨 말을 할지 사전에 제어하기 어렵기 때문이다.

 

이 설명이 좋았던 이유는, 단순히 “TTS도 된다”가 아니라 왜 TTS를 개별 단계로 쓰는가까지 설명하고 있기 때문이다. 실제 프로젝트에서는 자연스러움도 중요하지만, 어떤 답이 나갈지 예측 가능하고 제어 가능해야 할 때가 많다. 특히 게임, 도슨트, 키오스크, 교육 콘텐츠처럼 의도한 말투와 문장을 유지해야 하는 경우라면, 문서가 말한 것처럼 중간에 텍스트 단계를 분명히 두는 편이 더 실용적이다. 단, 그 대신 처리 단계가 늘어나면서 시간이 조금 더 걸릴 수 있다는 점도 같이 적어두었다.


3. 이번 테스트에서 사용한 TTS 모델

기록 기준으로 단순 TTS에는 gpt-4o-mini-tts 모델을 사용했다. 문서에는 “단순히 TTS(Text To Speech)를 사용하면 gpt-4o-mini-tts 모델에게 특정 방식으로 또는 특정 어조로 말하도록 요청할 수 있다”고 적혀 있다. 즉, 단순히 문장을 읽게 하는 것만이 아니라, 어느 정도의 말투 지시도 함께 줄 수 있다는 의미다. 이 점은 텍스트 생성 파트에서 Role로 응답 스타일을 제어했던 것과 닮아 있다. 여기서는 그 제어 대상이 문장 스타일이 아니라 음성의 태도와 인상 쪽으로 옮겨간 셈이다.

 

이 부분은 실제로 꽤 매력적이다. 단순 TTS 엔진은 보통 “텍스트를 읽는다” 수준에 머무는 경우가 많은데, 여기서는 어느 정도의 스타일 지시가 가능하다는 점이 다르다. 예를 들어 같은 문장이라도 차분하게 읽게 할지, 활기차게 읽게 할지, 안내 방송처럼 읽게 할지를 텍스트 지시로 조정할 수 있다는 뜻이다. Unity 프로젝트 안에서 캐릭터 보이스 느낌을 빠르게 확인해보기에는 꽤 좋은 조건이라고 느꼈다.


4. Scene 구성은 어떻게 했는가

문서에서 정리한 TTS Scene 구성은 상당히 단순하다. Generate를 호출할 수 있는 버튼 하나, AudioSource를 가진 오브젝트 하나, 그리고 OpenAI_TTS 스크립트를 가진 오브젝트 하나만 있으면 기본 구성이 끝난다고 적혀 있다. 실제로 TTS의 본질은 “텍스트를 보내고, 돌아온 오디오를 재생한다”이기 때문에 초반 테스트 단계에서는 이 정도가 가장 효율적이다. UI를 과하게 얹기보다, 먼저 음성이 재생되는지부터 확인하는 흐름이 맞다.

이 구성이 좋은 이유는 실패 지점이 분명해진다는 데 있다. 버튼이 눌리지 않는 문제, 스크립트 호출 문제, 응답 수신 문제, AudioClip 생성 문제, AudioSource 재생 문제를 단계별로 나눠서 볼 수 있다. 반대로 처음부터 대화형 UI나 자막 시스템까지 올려버리면 어디서 막혔는지 파악하기 어려워진다. 개인적으로도 TTS처럼 입출력이 확실한 기능은 이런 최소 Scene으로 먼저 확인하는 게 가장 맞다고 느꼈다.


5. TTS 입력은 어떻게 설계했는가

문서에서는 TTS 요청에 들어가는 핵심 입력값을 두 가지로 정리한다. 하나는 Contents, 즉 실제로 음성으로 변환할 텍스트다. 다른 하나는 Instructions, 즉 보이스가 어떤 지침이나 태도를 가져야 하는지에 대한 설명이다. 쉽게 말해 Contents는 “무슨 말을 할지”, Instructions는 “어떻게 말할지”에 해당한다. 이 분리가 꽤 직관적이었다. 텍스트 생성에서 Developer와 User 역할을 나눴다면, 여기서는 음성 생성에서 내용과 스타일 지시를 나눈 셈이다.

 

이 구조는 실제 활용에서도 유용해 보였다. 예를 들어 동일한 문장을 여러 캐릭터가 말하게 하고 싶다면, Contents는 그대로 두고 Instructions만 바꾸면 된다. 반대로 같은 말투를 유지하면서 문장만 바꾸고 싶다면 Instructions를 고정하면 된다. 이런 식으로 분리해두면, 이후 게임 대사나 NPC 응답, 가이드 음성 같은 데 확장할 때 재사용성이 좋아진다. 문서가 간단한 테스트 코드 안에서도 이 구분을 이미 가져간 건 꽤 좋은 설계 포인트였다.


6. 코드 구조는 텍스트 생성과 얼마나 비슷했는가

기록대로라면 TTS 코드는 텍스트 생성기와 유사한 흐름을 가진다. 즉, OpenAI 설정을 받아 클라이언트를 만들고, 버튼 또는 특정 입력으로 요청을 보낸 뒤, 응답을 받아 처리하는 구조다. 다만 마지막 단계가 다르다. 텍스트 생성은 문자열을 Console에 찍으면 끝이지만, TTS는 반환된 오디오 데이터를 Unity가 재생할 수 있는 형태로 바꿔야 한다. 결국 핵심은 “응답을 받는다”가 아니라 “응답을 AudioClip으로 만들고 AudioSource에 넣어 재생한다” 쪽에 있다.

그래서 이 파트는 코드량 자체보다도 오디오 응답 포맷이 더 중요하게 느껴졌다. 텍스트나 이미지는 응답이 눈으로 확인되기 때문에 디버깅이 비교적 쉽다. 반면 TTS는 오디오 포맷이 맞지 않으면 아무 소리도 안 나거나, 디코딩 단계에서 바로 에러가 나버린다. 문서가 ResponseFormat 이슈를 별도로 남겨둔 이유도 이 때문이라고 봤다.


7. 실제로 부딪힌 포맷 이슈

이번 TTS 파트에서 가장 중요한 실전 포인트는 포맷 문제였다. 문서에는 “Whisper 모델의 경우에는 같은 코드로 테스트했을 경우 지원하지 않았고, ResponseFormat의 경우 Wav로 지정하면 Unity가 AudioClip을 디코딩 하는 과정에서 에러를 발생시켰다”고 적혀 있다. 즉, 이 단계에서는 단순히 모델만 맞추면 끝나는 게 아니고, Unity가 받아서 처리할 수 있는 오디오 포맷인지까지 같이 봐야 했다.

 

이 기록은 생각보다 중요하다. 많은 예제 글이 API 요청 성공 여부까지만 보여주는데, 실제 Unity 프로젝트에서는 그 다음 단계가 더 문제다. 응답이 정상이어도 Unity 쪽 디코딩이 실패하면 결국 결과를 쓸 수 없다. 특히 WAV처럼 익숙한 포맷이라도 API 응답 구조와 Unity 디코딩 방식이 맞지 않으면 문제가 생길 수 있다는 점은 직접 겪어보지 않으면 놓치기 쉽다. 그래서 이 문서는 “지원했다/안 했다”를 넘어, 실제로 Unity에서 재생 가능한가를 기준으로 기록을 남겼다는 점이 좋았다.


8. 실제 응답 속도는 어느 정도였는가

기록에는 응답 속도에 대한 체감도 남아 있다. 문서 기준으로 말해야 할 내용이 짧은 경우 빠른 속도로 응답이 왔고, 50자 정도의 글은 1초 정도의 지연시간이 있었다고 적혀 있다. 완전 실시간이라고 보기는 어렵지만, 짧은 문장을 읽게 하는 용도라면 충분히 쓸 만한 수준으로 느껴진다. 특히 단순 테스트나 짧은 안내 문장, 한두 문장짜리 NPC 응답 정도에는 체감상 큰 무리가 없을 수 있다.

 

이 수치를 보면서 든 생각은, TTS는 텍스트 생성보다 응답 길이에 따라 체감 차이가 더 직접적이라는 점이었다. 텍스트는 1초가 조금 늦어도 UI상으로 크게 문제되지 않을 때가 많다. 하지만 음성은 버튼을 눌렀는데 잠깐 정적이 흐르면 바로 어색해진다. 그래서 실제 서비스에 넣을 때는 짧은 응답을 우선 설계하거나, 응답 시작 전에 로딩 느낌을 줄 수 있는 연출을 넣는 게 중요하겠다는 생각이 들었다.


9. 이번 단계에서 느낀 점

이번 TTS 파트를 정리하면서 가장 크게 느낀 건, 텍스트 생성 결과를 실제로 “말하게” 만드는 순간 인터랙션 체감이 확 달라진다는 점이었다. Console에 문장이 찍히는 것과, Unity 오브젝트가 실제로 소리를 내는 것은 완전히 다른 경험이다. 특히 캐릭터, 가이드, 도슨트, 보이스 피드백 같은 요소를 생각하면 TTS는 단순 부가 기능이 아니라 사용자 경험 자체를 바꿀 수 있는 장치라고 느껴졌다. 문서가 이미지 파트 다음에 TTS를 배치한 것도 그런 이유로 읽혔다.

 

반면 구현은 생각보다 단순하지만, 실제 적용에는 꽤 세심한 조정이 필요해 보였다. 포맷 문제, 응답 지연, 말투 지시, AudioClip 디코딩 안정성 같은 요소를 다 신경 써야 하기 때문이다. 특히 “코드는 텍스트 생성과 비슷한데 왜 실제 체감은 더 어렵지?”라는 느낌이 있었는데, 그 이유는 결국 텍스트와 달리 출력 형식이 오디오이기 때문이라고 본다. 출력 매체가 바뀌는 순간 고려해야 할 품질 조건도 같이 늘어난다.


10. 여기서 어디까지 확장할 수 있을까

문서의 뒤쪽 내용을 보면, 이 TTS는 단독 기능으로 끝나지 않는다. 이후 STT와 LLM을 이어서 사용자 입력 → STT → LLM → TTS → 출력 구조로 연결하는 흐름으로 확장된다. 즉, 지금 단계의 TTS는 그냥 “문장을 읽는 기능”이 아니라, 나중에 대화형 AI 도슨트를 만들기 위한 출력 모듈에 가깝다. 문서에서도 Realtime API처럼 STT, LLM, TTS를 하나로 묶은 서비스가 있지만, 직접 단계를 나눠 구현하면 더 세밀한 제어가 가능하다고 설명한다.

 

이 흐름을 보고 나니 이번 4편의 의미가 더 분명해졌다. 이번 글은 단순 TTS 테스트 같지만, 실제로는 다음 단계인 STT나 전체 도슨트 구조를 위한 준비 단계이기도 하다. 출력 음성의 품질과 지연 시간을 여기서 먼저 감 잡아둬야, 이후 입력 음성과 대화 흐름을 붙였을 때 어디가 병목인지도 판단할 수 있다. 즉, 이번 파트는 기능 하나 추가가 아니라 대화형 구조의 후반부를 먼저 검증한 셈이라고 보는 편이 맞다.


마무리

이번 글에서는 Unity에서 OpenAI API를 이용해 텍스트를 음성으로 변환하고, 그 결과를 AudioSource로 재생하는 흐름을 정리했다. 핵심은 gpt-4o-mini-tts 같은 모델을 이용해 내용과 말투 지시를 함께 넘기고, Unity 씬 안에서는 버튼, OpenAI_TTS 스크립트, AudioSource 정도의 최소 구성으로 먼저 테스트하는 것이었다. 구현 구조는 텍스트 생성과 비슷하지만, 실제로는 오디오 응답 포맷과 Unity 디코딩 과정이 더 중요한 변수로 작용했다. 기록상으로도 짧은 문장은 빠르게 응답했고, 50자 정도는 1초 내외의 지연이 있었다.

 


참고 링크

OpenAI Platform
https://platform.openai.com

 

OpenAI Platform

 

platform.openai.com

 

OpenAI Pricing
https://platform.openai.com/docs/pricing

 

Pricing | OpenAI API

Pricing information for the OpenAI platform.

developers.openai.com

 

OpenAI Docs Overview
https://platform.openai.com/docs/overview

 

OpenAI Platform

 

platform.openai.com

 

OpenAI Audio & Speech Guide
https://platform.openai.com/docs/guides/text-to-speech

 

Text to speech | OpenAI API

Learn how to turn text into lifelike spoken audio with the OpenAI API.

developers.openai.com

 

Unity OpenAI SDK (RageAgainstThePixel)
https://github.com/RageAgainstThePixel/com.openai.unity

 

GitHub - RageAgainstThePixel/com.openai.unity: A Non-Official OpenAI Rest Client for Unity (UPM)

A Non-Official OpenAI Rest Client for Unity (UPM). Contribute to RageAgainstThePixel/com.openai.unity development by creating an account on GitHub.

github.com

※ 본 글은 직접 테스트하고 정리한 내용을 기반으로 작성했으며, 문서 구조 정리와 문장 다듬기에는 AI의 도움을 일부 활용했습니다.

반응형