tencent cloud

文档反馈

跑通 Unreal Sample Project

最后更新时间:2024-01-18 11:53:34

    本文主要介绍如何快速运行 GME Unreal Sample Project,并将工程示例代码接入到项目中。

    跑通 Unreal Sample Project

    环境要求

    • UnrealEngine 4.22 及以上版本。
    • Microsoft Visual Studio。
    • 能运行 UnrealEngine 工程的配置环境。

    前提条件

    请提前申请开通 GME 实时语音、语音消息服务,获取到 AppId 以及 Key。申请 GME 服务,详情请参见 服务开通appId 对应控制台的 AppID,authKey 对应控制台的权限密钥。

    操作步骤

    步骤1:下载工程

    通过 下载指引 下载 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:实时语音功能界面。
    • Voice Message:语音消息功能界面。

    单击 Login,进行初始化,再单击 Voice Chat 进入实时语音房间配置界面。

    3)实时语音进房

    • RoomId:房间号码,同房间的人可以互相语音交流。
    • RoomType:请使用 Fluency 进入房间。
    • JoinRoom:进入语音房间。
    • Back:后退到上一个界面。

    配置好实时语音房间号后,单击 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 按钮,对着麦克风进行说话,放开后语音会转成文本显示在界面中。

    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 需要周期性的调用 Poll 函数。在 UEDemoLevelScriptActor.cpp 脚本中的 Tick 中调用。

    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 音效文档。在工程中,首先初始化 3D 音效功能,相关代码在 ExperientialDemoViewController.cpp 中。

    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);
    }
    
    
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持