본문은 GME Unreal Sample Project를 빠르게 실행하고 예시 코드를 프로젝트에 통합하는 방법을 설명합니다.
Unreal Sample Project 실행
환경 요건
Unreal Engine 4.22 이상.
Microsoft Visual Studio.
UnrealEngine 프로젝트를 실행할 수 있는 구성 환경.
전제 조건
GME 음성 채팅 및 음성 메시지 서비스를 사전에 신청하고 AppId 및 Key를 받아야 합니다. GME 서비스 신청 방법은 서비스 활성화를 참고하십시오. appId는 콘솔 AppID에 해당하고, authKey는 콘솔의 권한 키에 해당합니다. 작업 단계
1단계: 프로젝트 다운로드
SDK 다운로드 가이드의 안내에 따라 Unreal Sample Project를 다운로드합니다. UE5와 UE4의 Demo 구성이 다르기 때문에 해당 엔진 버전에 대한 Sample Project를 다운로드해야 합니다. 2단계: 프로젝트 구성
다운로드 후 프로젝트 디렉터리를 열고 Source\\UEDemo1 경로에서 UserConfig.cpp를 찾아 붉은색 상자의 appID와 appKey를 적용된 GME 콘솔 [서비스관리-애플리케이션 설정]에서 AppID와 권한 키로 변경합니다.
3단계: 컴파일 및 실행
1) 프로그램 실행
편집기에서 을(를) 클릭하여 프로그램을 실행합니다. 2) 초기화
UserID: openid와 동일. openID는 애플리케이션에서 사용자의 고유 식별자이며 각 터미널의 openid는 고유해야 합니다.
Voice Chat: 음성 채팅 기능 UI입니다.
Voice Message: 음성 메시지 기능 UI입니다.
Login을 클릭하여 초기화한 후 Voice Chat 을 클릭하여 실시간 음성 채팅방 설정 페이지로 이동합니다.
3) 음성 채팅방 입장
RoomId: 방 ID입니다. 같은 방에 있는 사용자는 음성으로 서로 통신할 수 있습니다.
RoomType: Fluency를 사용하여 방에 입장합니다.
JoinRoom: 음성 채팅 방에 입장합니다.
Back: 이전 페이지로 돌아갑니다.
음성 채팅방 ID를 설정한 후, JoinRoom를 클릭하여 방에 입장합니다.
4) 실시간 음성 채팅 사용
페이지에 방 입장을 위한 RoomID와 로컬 openID가 표시됩니다.
Mic: 마이크를 켜려면 선택합니다.
Speaker: 스피커를 켜려면 선택합니다.
3D Voice Effect: 3D 사운드 효과를 활성화하려면 선택합니다.
Voice Change: 음성 변조 효과를 선택합니다.
로컬에서 Mic와 Speaker를 선택한 후, 다른 기기에서 위의 과정을 반복하여 같은 방에 들어가 Mic와 Speaker를 선택하면 양측의 통신이 가능합니다.
두 터미널 모두 3D Voice Effect를 선택한 경우, 키보드 [A] [S] [D] [W] 키를 사용하여 방향을 변경하여 음성의 3D 스테레오 효과를 경험할 수 있습니다.
5) 음성 메시지 사용
Language: 텍스트 변환 대상 언어를 선택합니다. 예를 들어 중국어를 사용하는 경우 중국어를 선택합니다.
Audio: 녹음 후 클릭하면 들을 수 있습니다.
Audio-to-Text: 텍스트로 변환된 음성 메시지 내용입니다.
Push To Talk: 길게 누르면 녹음됩니다.
Back: 이전 페이지로 돌아갑니다.
Push to Talk를 길게 누르고 마이크에 대고 말합니다. 버튼을 놓으면 음성 메시지가 텍스트로 변환되어 UI에 표시됩니다.
Sample Project 코드 소개
GME 실시간 음성 채팅을 사용하는 주요 프로세스는 Init > EnterRoom > EnableMic > EnableSpeaker입니다. Sample Project의 주요 코드는 BaseViewController.cpp 및 ExperientialDemoViewController.cpp에 있습니다.
초기화
초기화 코드는 BaseViewController.cpp 파일의 InitGME 함수에 있습니다. 초기화, 음성 메시지 인증 초기화, TMGDelegate 콜백 설정이 포함됩니다.
int UBaseViewController::InitGME(std::string sdkAppId, std::string sdkAppKey, std::string userId) {
int nAppid = atoi(sdkAppId.c_str());
int ret = ITMGContextGetInstance()->Init(sdkAppId.c_str(), userId.c_str());
ITMGContextGetInstance()->SetTMGDelegate(this);
int RetCode = (int) ITMGContextGetInstance()->CheckMicPermission();
FString msg = FString::Printf(TEXT("check Permission retcode =%d"), RetCode);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, *msg);
char strSig[128] = {0};
unsigned int nLength = 128;
nLength = QAVSDK_AuthBuffer_GenAuthBuffer(nAppid, "0", userId.c_str(), sdkAppKey.c_str(), (unsigned char *)strSig, nLength);
ITMGContextGetInstance()->GetPTT()->ApplyPTTAuthbuffer(strSig, nLength);
m_appId = sdkAppId;
m_appKey = sdkAppKey;
m_userId = userId;
m_isEnableTips = false;
m_tipsMark = 0;
return ret;
}
GME를 사용하려면 UEDemoLevelScriptActor.cpp 스크립트의 Tick에 있는 Poll 함수를 주기적으로 호출해야 합니다.
void AUEDemoLevelScriptActor::Tick(float DeltaSeconds) {
Super::Tick(DeltaSeconds);
m_pTestDemoViewController->UpdateTips();
m_pCurrentViewController->UpdatePosition();
ITMGContextGetInstance()->Poll();
}
방 입장
방 입장 코드는 BaseViewController.cpp 파일의 EnterRoom 함수에 있습니다.
void UBaseViewController::EnterRoom(std::string roomID, ITMG_ROOM_TYPE roomType) {
int nAppid = atoi(m_appId.c_str());
UserConfig::SetRoomID(roomID);
char strSig[128] = {0};
unsigned int nLength = 128;
nLength = QAVSDK_AuthBuffer_GenAuthBuffer(nAppid, roomID.c_str(), m_userId.c_str(), m_appKey.c_str(), (unsigned char *)strSig, nLength);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, TEXT("onEnterRoom"));
ITMGContextGetInstance()->EnterRoom(roomID.c_str(), roomType, strSig, nLength);
}
방 입장 콜백은 동일한 스크립트의 OnEvent 함수에 있습니다.
if (eventType == ITMG_MAIN_EVENT_TYPE_ENTER_ROOM) {
int32 result = JsonObject->GetIntegerField(TEXT("result"));
FString error_info = JsonObject->GetStringField(TEXT("error_info"));
if (result == 0) {
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 20.0f, FColor::Yellow, TEXT("Enter room success."));
}
else{
FString msg = FString::Printf(TEXT("Enter room failed. result=%d, info = %ls"), result, *error_info);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 20.0f, FColor::Yellow, *msg);
}
onEnterRoomCompleted(result, error_info);
장치 활성화
방 입장 성공 후 장치 활성화 코드는 ExperientialDemoViewController.cpp에 있습니다.
void UExperientialDemoViewController::onCheckMic(bool isChecked) {
//GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, L"onCheckMic");
ITMGContext *pContext = ITMGContextGetInstance();
if (pContext) {
ITMGAudioCtrl *pTmgCtrl = pContext->GetAudioCtrl();
if (pTmgCtrl) {
pTmgCtrl->EnableMic(isChecked);
}
}
}
void UExperientialDemoViewController::onCheckSpeaker(bool isChecked) {
//GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, L"onCheckSpeaker");
ITMGContext *pContext = ITMGContextGetInstance();
if (pContext) {
ITMGAudioCtrl *pTmgCtrl = pContext->GetAudioCtrl();
if (pTmgCtrl) {
pTmgCtrl->EnableSpeaker(isChecked);
}
}
}
3D 음향 효과
3D 음향 효과 연결에 대해서는 3D 음향 효과를 참고하십시오. 프로젝트에서는 먼저 ExperientialDemoViewController.cpp의 코드를 사용하여 3D 음향 효과 기능을 초기화합니다. void UExperientialDemoViewController::onCheckSpatializer(bool isChecked) {
char buffer[256]={0};
// snprintf(buffer, sizeof(buffer), "%s3d_model", getFilePath().c_str());
snprintf(buffer, sizeof(buffer), "%sgme_2.8_3d_model.dat", getFilePath().c_str());
int ret1 = ITMGContextGetInstance()->GetAudioCtrl()->InitSpatializer(buffer);
int ret2 = ITMGContextGetInstance()->GetAudioCtrl()->EnableSpatializer(isChecked, false);
FString msg = FString::Printf(TEXT("InitSpatializer=%d, EnableSpatializer ret=%d"), ret1, ret2);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, msg);
}
UEDemoLevelScriptActor.cpp 스크립트의 Tick에서 UpdatePosition 함수를 호출합니다.
void AUEDemoLevelScriptActor::Tick(float DeltaSeconds) {
Super::Tick(DeltaSeconds);
m_pTestDemoViewController->UpdateTips();
m_pCurrentViewController->UpdatePosition();
ITMGContextGetInstance()->Poll();
}
void UBaseViewController::UpdatePosition() {
if (!m_isCreated)
return;
ITMGRoom *pTmgRoom = ITMGContextGetInstance()->GetRoom();
if (!pTmgRoom)
{
return;
}
int nRange = GetRange();
pTmgRoom->UpdateAudioRecvRange(nRange);
FVector cameraLocation = UGameplayStatics::GetPlayerCameraManager(m_pActor->GetWorld(), 0)->GetCameraLocation();
FRotator cameraRotation = UGameplayStatics::GetPlayerCameraManager(m_pActor->GetWorld(), 0)->GetCameraRotation();
FString msg = FString::Printf(TEXT("location(x=%.2f,y=%.2f,z=%.2f), rotation(pitch=%.2f,yaw=%.2f,roll=%.2f)"),
cameraLocation.X, cameraLocation.Y, cameraLocation.Z, cameraRotation.Pitch, cameraRotation.Yaw, cameraRotation.Roll);
int position[] = { (int)cameraLocation.X,(int)cameraLocation.Y, (int)cameraLocation.Z };
FMatrix matrix = ((FRotationMatrix)cameraRotation);
float forward[] = { matrix.GetColumn(0).X,matrix.GetColumn(1).X,matrix.GetColumn(2).X };
float right[] = { matrix.GetColumn(0).Y,matrix.GetColumn(1).Y,matrix.GetColumn(2).Y };
float up[] = { matrix.GetColumn(0).Z,matrix.GetColumn(1).Z,matrix.GetColumn(2).Z };
pTmgRoom->UpdateSelfPosition(position, forward, right, up);
SetPositionInfo(msg);
}
ExperientialDemoViewController.cpp에서 3D 효과를 활성화합니다.
void UExperientialDemoViewController::onCheckSpatializer(bool isChecked) {
char buffer[256]={0};
// snprintf(buffer, sizeof(buffer), "%s3d_model", getFilePath().c_str());
snprintf(buffer, sizeof(buffer), "%sgme_2.8_3d_model.dat", getFilePath().c_str());
int ret1 = ITMGContextGetInstance()->GetAudioCtrl()->InitSpatializer(buffer);
int ret2 = ITMGContextGetInstance()->GetAudioCtrl()->EnableSpatializer(isChecked, false);
FString msg = FString::Printf(TEXT("InitSpatializer=%d, EnableSpatializer ret=%d"), ret1, ret2);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.0f, FColor::Yellow, msg);
}
문제 해결에 도움이 되었나요?