Carrot
본문 바로가기
Unity/OpenAI

[OpenAI API] 음성 인식 기반 AI NPC 구현하기

by 독기품은토끼 2026. 2. 26.

오늘은 기존에 구현해 두었던 AI NPC 대화 시스템에

Whisper API를 결합하여 음성으로 NPC와 상호작용하는 구조를 만들어보려고 한다.

 

// NPC 설정 추가
public string currentPrompt = "당신은 NPC 캐릭터 RobotKyle입니다. 질문에 답해주세요.";
public Text uiText;

// 이벤트 등록
private void Start(){
    WhisperManager.Instance.OnReceivedWhisper += RecievedWhisper;
}

private void RecievedWhisper(string transcribedText){
    StartCoroutine(SendOpenAIRequest(currentPrompt, transcribedText, uiText));
}

 

우선 Whisper API 결과를 기존 OpenAI 대화 시스템에 연결해주는 작업을 해주었다.

 

즉, WhisperManager에서 음성 인식이 완료되면 텍스트를 이벤트로 전달하고
OpenAIManager는 이를 구독하여 기존 GPT 요청 로직을 그대로 재사용하도록 구성했다.

 

// 액션 추가
public event Action OnReceivedMessage;

public IEnumerator SendOpenAIRequest(string prompt, string message, Text resultText)
{
	// 생략

    using (UnityWebRequest request = new UnityWebRequest(apiUrl, "POST"))
    {
        // 생략

        else
        {
            string responseText = request.downloadHandler.text;
            Debug.Log("Response : " + responseText);

            var responseData = JsonUtility.FromJson<OpenAIResponse>(responseText);
            if (responseData.choices != null && responseData.choices.Length > 0)
            {
                string assistantMessage = responseData.choices[0].message.content;
                resultText.text = assistantMessage;
                OnReceivedMessage?.Invoke(); // 이벤트 호출
            }
            else
                Debug.LogWarning("No valid response from the assistant");
        }
    }
}

 

그 다음 NPC 애니메이션과 연결해주기 위해 OnReceivedMessage 이벤트를 생성하여 GPT 응답을 받은 시점에 호출하도록 해주었다.

 

응답 시점에 호출해준 이유는 이 이벤트를 기준으로 NPC가 대답을 시작하는 시점을 명확히 분리하기 위함이다!

 

void Start()
{
    //// 입력 발생 시 실행되는 이벤트
    //UIManager.Instance.inputField.onValueChanged.AddListener(OnInputFieldChanged);

    //// 입력 완료 시 실행되는 이벤트
    //UIManager.Instance.inputField.onSubmit.AddListener(OnInputFieldSubmit);

    WhisperManager.Instance.OnStartRecording += OnInputFieldChanged; // 녹음 시작 시 Listen Anim 호출
    WhisperManager.Instance.OnStopRecording += OnInputFieldSubmit; // 녹음 중지 시 Think Anim 호출

    OpenAIManager.Instance.OnReceivedMessage += StartTalk; // Talk Anim 호출
}

private void StartTalk()
{
    StartCoroutine(TalkThenIdle());
}

public IEnumerator TalkThenIdle()
{
    balloon.SetActive(false);
    anim.SetTrigger("talk");
    yield return new WaitForSeconds(5f);
    anim.SetTrigger("idle");
}

 

그 후 NPCManager 스크립트에서 기존에 사용하던 이벤트와 결합시켜주었다.

  • 녹음 시작 시 듣는 애니메이션 호출
  • 녹음 종료 시 고민하는 애니메이션 호출
  • GPT를 통해 답변을 받은 것을 Text UI에 나타나도록

 

당신은 NPC 캐릭터 RobotKyle입니다. 질문에 답해주세요

 

prompt에 당장은 위와 같이 이렇게 입력해놓았는데

게임 컨셉에 맞게 변경해주면 좀 더 생동감 있는 답변을 받을 수 있다고 한다.

 

 

질문을 "Chat GPT는 무엇인가요?" 라고 했는데

Whisper가 인식한 내용은 어처구니 없는 채취 PT ㅋㅋㅋ

 

 

 

Speech to text | OpenAI API

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

developers.openai.com

 

공식 문서를 확인해보면

이럴 경우 후처리를 통해 보완하는 방법에 대해서 설명하는 부분은 없어서 아쉬웠다..ㅠ

 

그래도 그나마 좀 보완할 수 있는 방법이라면

prompt 에 컨텍스트를 제시해서 인식 품질을 높이는 방법 뿐이라고 한다!

 

public string currentPrompt =
"당신은 NPC 캐릭터 RobotKyle입니다. 질문에 답해주세요." + "특히 철자 오류를 교정하세요" + "Chat gpt";

 

그래서 이렇게 수정해주었더니 이제야 좀 인식이 잘 되었다.

 

추가로 GPT에 물어보니 API를 두번 호출해서 하는 방식이 있다는데 그러면 연산 속도도 그렇고.. 무엇보다 돈이 많이 드니까 ..^^..

아무리 기술이 발전한다해도.. 당분간은 실무에서는 잘 쓰이지 않을 것 같당