유니티 Wit.ai와 Meta Voice SDK를 활용한 음성 인식

Unity Meta SDK를 사용할 때 음성 인식 기능을 구현하려면 Meta Voice SDKWit.ai을 활용하시면 됩니다. 

 

GitHub - oculus-samples/voicesdk-samples-whisperer: Oculus Voice SDK showcase demonstrating the use of Voice SDK in Unity. This

Oculus Voice SDK showcase demonstrating the use of Voice SDK in Unity. This project contains the source code for the "Whisperer" demo available on App Lab. The Oculus SDK and other suppor...

github.com

 

 

Meta Developers

 

developers.meta.com

 


Wit.ai란?

Wit.ai는 자연어 처리(NLP) 플랫폼으로, 사용자의 텍스트나 음성 입력을 이해하고 처리하여 의도(Intent)와 개체(Entity)를 추출합니다. 이를 통해 챗봇, 음성 인식 시스템 등 다양한 대화형 애플리케이션을 만들 수 있습니다.

 

자연어 처리(NLP)에서 인텐트(Intent)엔티티(Entity)는 사용자의 발화를 이해하는 데 핵심적인 개념입니다.

인텐트(Intent)는 사용자가 표현한 문장에서 의도나 목적을 나타내는 요소입니다. 예를 들어, "오늘 서울 날씨 알려줘"라는 문장에서 사용자의 인텐트는 '날씨 정보 요청'입니다.
엔티티(Entity)는 문장에서 특정한 개체나 데이터를 나타내는 단어나 구를 말합니다. 위의 예문에서 "서울"은 '지역' 엔티티에 해당합니다.

 

 

문장 인텐트 엔티티
"내일 오후 2시에 알람 설정해줘." 알람 설정 날짜: 내일
시간: 오후 2시
"김치찌개 레시피 알려줘." 레시피 요청 요리명: 김치찌개
"서울에서 부산까지 기차표 예매해줘." 기차표 예매 출발지: 서울
도착지: 부산

Wit 설정

 

Wit.ai

 

wit.ai

먼저 홈페이지에 들어가서 로그인을 해줍니다.

Setting Flow / Wit Configuration 만드는 방법

 

로그인 후 Settings에 들어가서 Server Access Token을 복사해서 에디터 상단 Voice SDK - Get Started를 누른 후 새로 생긴 창에 붙여줍니다. 그 후 Create를 프로젝트 내에 저장해줍니다. 그렇게 하면 Wit Configuration이 생성된 것을 볼 수 있습니다.

 

학습 방법

Understanding 탭에 돌아가서 Utterance에 학습시키고 하는 문장을 적습니다.

예를 들어, "Move Forward" 라는 간단한 문장을 만들겠습니다. 그 후 Entity에 해당하는 단어를 더블클릭하면 Entity를 Create 혹은 이미 만들어둔 Entitiy를 선택할 수 있습니다. 저는 change_position이라는 entity를 만들어서 Forward에 매핑시켜주겠습니다.

 

그 다음 Intent는 미리 만들어오셔야 합니다. Intent의 경우 저는 큐브를 움직일 목적으로 문장을 학습시킬 예정이므로 Intent를 "change cube" 라고 간단하게 만들어줬습니다.

Intent / Entities

Intent안에는 만들어진 Entities들이 포함되어 있습니다.

Utterances

Utterances탭에는 Entity들이 들어가 있으며 관련된 Entity를 추가할 수 잇습니다.


유니티에서 Voice SDK사용하는 방법

Voice Experience To Scene을 통해 App Voice Experience컴포넌트 추가

위 사진을 보고 따라하시면 인스펙터에 App Voice Experience객체가 생성되는 것을 볼 수 있습니다. 객체에 Wit Configuration에 아까 만든 Wit Configuration SO가 할당되어 있는 것을 볼 수 있습니다.

 

Voice SDK사용 Flow

그 후, 에디터 상단에 [Meta] - [Voice Sdk] - [Understanding Viewer] 를 눌러줍니다.

Understanding Viewer 창

Understanding Viewer이 생기는데 Utterance에 우리가 만든 Utterance를 입력해줍니다. 그리고 Send를 누르면 몇 초 후에 위 사진처럼 entities를 펼쳐보면 value라는게 보이는데 그거를 클릭하면 아까 만든 App Voice Experience객체에 추가한다는 것이 뜹니다. 눌러주면,

Response Matcher

Response Matcher라는 컴포넌트가 App Voice Experience객체에 추가되는 것을 확인할 수 있습니다. 또한, intent에 우리가 설정한 change_cube라는 것도 잘 들어가 있습니다.


코드로 Parsing하기

using Meta.WitAi;
using UnityEngine;

namespace EscapiaWorld
{
    public class CubeController : MonoBehaviour
    {
        [SerializeField] private VoiceService voiceService;

        public MeshRenderer MeshRenderer;
        public Transform Cube;
        
        public void SetColor(string[] entityValues)
        {
            if(entityValues.Length > 0 && ColorUtility.TryParseHtmlString(entityValues[0], out var newColor))
            {
                for (int i = 0; i < entityValues.Length; i++)
                {
                    Debug.Log($"[SetColor]EntityValue[{i}] : {entityValues[i]}");
                }
                MeshRenderer.material.color = newColor;
            }
        }

        public void MovePosition(string[] entityValues)
        {
            if (entityValues.Length > 0)
            {
                for (int i = 0; i < entityValues.Length; i++)
                {
                    Debug.Log($"[MovePosition]EntityValue[{i}] : {entityValues[i]}");
                }

                Debug.Log($"To Upper  : {entityValues[0].ToUpper()}");
                switch (entityValues[0].ToUpper())
                {
                    case "FORWARD":
                        Cube.Translate(Vector3.forward);
                        Debug.Log("Move Forward");
                        break;
                    default:
                        break;
                }
            }
        }
    }
}

코드를 만들어준 다음, 아래 사진처럼 Respnse Matcher의 On Multi Value Event 이벤트에 만든 함수를 연결하시면 됩니다.

 

결과는 아래 유튜브 영상을 봐주세요.

결과 동영상 / Meta Voice SDK with Wit.ai

 


VoiceEvents종류

VoiceEvents는 VoiceService에서 발생하는 다양한 이벤트를 포함하는 클래스입니다. 

이벤트 설명
OnStartListening 음성 인식이 시작될 때 호출됩니다.
OnPartialTranscription 사용자의 발화 중간에 부분적인 텍스트 변환 결과를 제공합니다.
OnFullTranscription 사용자의 발화가 완료되면 전체 텍스트 변환 결과를 제공합니다.
OnError 음성 인식 과정에서 오류가 발생하면 호출됩니다.
OnComplete 음성 인식 프로세스가 모든 단계를 마치고 종료될 때 호출됩니다.
OnMinimumWakeThresholdHit 음성 인식 시작을 위한 최소 웨이크 업 임계값에 도달하지 못했을 때 호출됩니다.
OnMicStartedListening 마이크가 실제로 녹음을 시작할 때 호출됩니다.
OnMicStoppedListening 마이크가 녹음을 중지할 때 호출됩니다.

 

OnMicStartedListening과 OnStartListening은 모두 음성 인식 과정에서 '시작'과 관련된 이벤트지만, 그 의미와 발생 시점에서 차이가 있습니다.

  • OnMicStartedListening: 마이크가 실제로 녹음을 시작할 때 호출됩니다. 즉, 물리적인 마이크 장치가 활성화되어 오디오 데이터를 수집하기 시작하는 시점을 나타냅니다.
  • OnStartListening: 음성 인식 프로세스가 시작될 때 호출됩니다. 이는 시스템이 음성 데이터를 처리하고 인식하기 위한 준비가 완료되었음을 의미합니다.

예시 코드

using UnityEngine;
using UnityEngine.Events;

public class VoiceRecognitionHandler : MonoBehaviour
{
    [SerializeField] private VoiceService voiceService;

    private void Awake()
    {
        // 각 이벤트에 대한 리스너 등록
        voiceService.VoiceEvents.OnStartListening.AddListener(OnStartListening);
        voiceService.VoiceEvents.OnPartialTranscription.AddListener(OnPartialTranscription);
        voiceService.VoiceEvents.OnFullTranscription.AddListener(OnFullTranscription);
        voiceService.VoiceEvents.OnError.AddListener(OnError);
        voiceService.VoiceEvents.OnComplete.AddListener(OnComplete);
    }

    private void OnStartListening()
    {
        Debug.Log("음성 인식을 시작합니다.");
        // 추가적인 로직 구현
    }

    private void OnPartialTranscription(string partialText)
    {
        Debug.Log($"부분 인식 결과: {partialText}");
        // 추가적인 로직 구현
    }

    private void OnFullTranscription(string fullText)
    {
        Debug.Log($"전체 인식 결과: {fullText}");
        // 추가적인 로직 구현
    }

    private void OnError(string error, string message)
    {
        Debug.LogError($"오류 발생: {error} - {message}");
        // 오류 처리 로직 구현
    }

    private void OnComplete()
    {
        Debug.Log("음성 인식이 완료되었습니다.");
        // 추가적인 로직 구현
    }
}

 


그 외에 유틸리티 컴포넌트

둘 다 Lagacy UI를 사용하므로 주의한다