diff --git a/unreal/win/Config/DefaultEditor.ini b/unreal/win/Config/DefaultEditor.ini new file mode 100644 index 0000000..e69de29 diff --git a/unreal/win/Config/DefaultEngine.ini b/unreal/win/Config/DefaultEngine.ini new file mode 100644 index 0000000..ccb64eb --- /dev/null +++ b/unreal/win/Config/DefaultEngine.ini @@ -0,0 +1,17 @@ + + +[/Script/HardwareTargeting.HardwareTargetingSettings] +TargetedHardwareClass=Desktop +AppliedTargetedHardwareClass=Desktop +DefaultGraphicsPerformance=Maximum +AppliedDefaultGraphicsPerformance=Maximum + +[/Script/Engine.Engine] ++ActiveGameNameRedirects=(OldGameName="TP_Blank",NewGameName="/Script/NertcSampleCode") ++ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/NertcSampleCode") ++ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="NertcSampleCodeGameModeBase") + +[/Script/EngineSettings.GameMapsSettings] +EditorStartupMap=/Game/Home.Home +GameDefaultMap=/Game/Home.Home + diff --git a/unreal/win/Config/DefaultGame.ini b/unreal/win/Config/DefaultGame.ini new file mode 100644 index 0000000..aaf77d4 --- /dev/null +++ b/unreal/win/Config/DefaultGame.ini @@ -0,0 +1,3 @@ + +[/Script/EngineSettings.GeneralProjectSettings] +ProjectID=2696690546CC2874D37E89AE01510A16 diff --git a/unreal/win/Content/Home.umap b/unreal/win/Content/Home.umap new file mode 100644 index 0000000..07f0fe9 Binary files /dev/null and b/unreal/win/Content/Home.umap differ diff --git a/unreal/win/Content/UI.uasset b/unreal/win/Content/UI.uasset new file mode 100644 index 0000000..e25cee3 Binary files /dev/null and b/unreal/win/Content/UI.uasset differ diff --git a/unreal/win/NertcSampleCode.uproject b/unreal/win/NertcSampleCode.uproject new file mode 100644 index 0000000..34f9e4d --- /dev/null +++ b/unreal/win/NertcSampleCode.uproject @@ -0,0 +1,17 @@ +{ + "FileVersion": 3, + "EngineAssociation": "4.25", + "Category": "", + "Description": "", + "Modules": [ + { + "Name": "NertcSampleCode", + "Type": "Runtime", + "LoadingPhase": "Default", + "AdditionalDependencies": [ + "UMGEditor", + "UMG" + ] + } + ] +} \ No newline at end of file diff --git a/unreal/win/Plugins/PlaceHolder.log b/unreal/win/Plugins/PlaceHolder.log new file mode 100644 index 0000000..e69de29 diff --git a/unreal/win/README.md b/unreal/win/README.md new file mode 100644 index 0000000..3d17e22 --- /dev/null +++ b/unreal/win/README.md @@ -0,0 +1,50 @@ +您可以通过跑通 Sample Code,体验网易云信音视频通话功能。 + +## 前提条件 +请确认您已完成以下操作: + +>* 创建应用并获取 App Key。 +>* 开通音视频通话 2.0 服务。 + +## 开发环境要求 +请确保开发环境满足以下要求: + +>* 开发环境:Microsoft Visual Studio 2017(推荐)及以上版本 +>* 开发环境:Unreal Engine 4.25(推荐)及以上版本 +>* 操作系统:Microsoft Windows 7 及以上版本 +>* 编译器:Microsoft Visual C++ 2017 及以上版本 + +## 快速跑通 Sample Code +在运行示例项目之前,请在云信控制台中为指定应用开通调试模式。调试模式建议只在集成开发阶段使用,请在应用正式上线前改回安全模式。 + +1. 下载[示例项目](https://github.com/netease-im/G2-API-Examples)源码至您本地,并在SDK [下载中心](https://doc.yunxin.163.com/nertc/sdk-download?platform=UE)下载 Unreal engine Plugin 压缩包。 + +2. 进入到 Unreal Engine Sample Code 的 G2-API-Examples\unreal\win 目录,将 NertcPlugin 压缩包解压到 Plugins\ 目录下 + +3. 右键单击 NertcSampleCode.uproject ,选择 Generate Visual Studio project files, 生成 Visual Studio 解决方案。 + + ![](https://yx-web-nosdn.netease.im/common/45f0c71b96872f6e452e7500a5b5f574/%E5%9B%BE%E7%89%871.png) + +4. 双击上一步骤中生成的 NertcSampleCode.sln,打开解决方案。 + +5. 在 NertcUserWidget.cpp 配置文件中设置您的 AppKey 和 channeName 等信息。 + ![](https://yx-web-nosdn.netease.im/common/514d0000e4e5587d74cad332f4f084db/%E5%9B%BE%E7%89%872.png) + + | 参数 | 是否必选 | 描述| + | ------- | ------- |-----| + |g_appKey | 必选 | 请替换为云信控制台上您的应用对应的 AppKey。获取 AppKey的方法请参见[创建应用并获取 AppKey] (https://doc.yunxin.163.com/console/docs/TIzMDE4NTA?platform=console#%E8%8E%B7%E5%8F%96-appkey)。 | + |g_logPath|必选|设置日志路径| + |g_channelNam|必选|自定义的房间名。运行 Demo 时会加入该房间。| + |g_userID|必选|自定义的用户 ID。需要保证同一个房间中 g_userID 的唯一性。运行 Demo 时会使用该用户 ID 加入房间。| + + +6. 将 NertcSampleCode 工程设置为启动项目,按 F5 编译并运行工程。 + +7. 单击 Play 按钮,运行程序。 + ![](https://yx-web-nosdn.netease.im/common/dff0716bfce56deaef9c07cbf56eedf2/%E5%9B%BE%E7%89%873.png) + +8. 体验 Demo。 + +>* 单击 JoinChannel 按钮加入房间,房间名即为步骤 5 中您设置的 g_channelNam。若有两个人同时加入该房间内,即可进行语音通话。 + +>* 单击 LeaveChannel 离开房间。 diff --git a/unreal/win/Source/NertcSampleCode.Target.cs b/unreal/win/Source/NertcSampleCode.Target.cs new file mode 100644 index 0000000..8576c02 --- /dev/null +++ b/unreal/win/Source/NertcSampleCode.Target.cs @@ -0,0 +1,14 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; +using System.Collections.Generic; + +public class NertcSampleCodeTarget : TargetRules +{ + public NertcSampleCodeTarget( TargetInfo Target) : base(Target) + { + Type = TargetType.Game; + DefaultBuildSettings = BuildSettingsVersion.V2; + ExtraModuleNames.AddRange( new string[] { "NertcSampleCode" } ); + } +} diff --git a/unreal/win/Source/NertcSampleCode/NertcSampleCode.Build.cs b/unreal/win/Source/NertcSampleCode/NertcSampleCode.Build.cs new file mode 100644 index 0000000..633b587 --- /dev/null +++ b/unreal/win/Source/NertcSampleCode/NertcSampleCode.Build.cs @@ -0,0 +1,23 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; + +public class NertcSampleCode : ModuleRules +{ + public NertcSampleCode(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "NertcPlugin" }); + + PrivateDependencyModuleNames.AddRange(new string[] { }); + + // Uncomment if you are using Slate UI + // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); + + // Uncomment if you are using online features + // PrivateDependencyModuleNames.Add("OnlineSubsystem"); + + // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true + } +} diff --git a/unreal/win/Source/NertcSampleCode/NertcSampleCode.cpp b/unreal/win/Source/NertcSampleCode/NertcSampleCode.cpp new file mode 100644 index 0000000..2d521f6 --- /dev/null +++ b/unreal/win/Source/NertcSampleCode/NertcSampleCode.cpp @@ -0,0 +1,6 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "NertcSampleCode.h" +#include "Modules/ModuleManager.h" + +IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, NertcSampleCode, "NertcSampleCode" ); diff --git a/unreal/win/Source/NertcSampleCode/NertcSampleCode.h b/unreal/win/Source/NertcSampleCode/NertcSampleCode.h new file mode 100644 index 0000000..73cb863 --- /dev/null +++ b/unreal/win/Source/NertcSampleCode/NertcSampleCode.h @@ -0,0 +1,6 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" + diff --git a/unreal/win/Source/NertcSampleCode/NertcSampleCodeGameModeBase.cpp b/unreal/win/Source/NertcSampleCode/NertcSampleCodeGameModeBase.cpp new file mode 100644 index 0000000..764f4d3 --- /dev/null +++ b/unreal/win/Source/NertcSampleCode/NertcSampleCodeGameModeBase.cpp @@ -0,0 +1,5 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + + +#include "NertcSampleCodeGameModeBase.h" + diff --git a/unreal/win/Source/NertcSampleCode/NertcSampleCodeGameModeBase.h b/unreal/win/Source/NertcSampleCode/NertcSampleCodeGameModeBase.h new file mode 100644 index 0000000..cc34b12 --- /dev/null +++ b/unreal/win/Source/NertcSampleCode/NertcSampleCodeGameModeBase.h @@ -0,0 +1,17 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/GameModeBase.h" +#include "NertcSampleCodeGameModeBase.generated.h" + +/** + * + */ +UCLASS() +class NERTCSAMPLECODE_API ANertcSampleCodeGameModeBase : public AGameModeBase +{ + GENERATED_BODY() + +}; diff --git a/unreal/win/Source/NertcSampleCode/NertcUserWidget.cpp b/unreal/win/Source/NertcSampleCode/NertcUserWidget.cpp new file mode 100644 index 0000000..d47ca08 --- /dev/null +++ b/unreal/win/Source/NertcSampleCode/NertcUserWidget.cpp @@ -0,0 +1,81 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "NertcUserWidget.h" +#include + +const std::string g_appKey = "your appkey"; +const std::string g_logPath = "your log path"; +const std::string g_channelName = "your channel name"; +const uint64_t g_userID = 123; //your userID + +void UNertcUserWidget::NativeConstruct() +{ + Super::NativeConstruct(); + InitNertcEngine(g_appKey, g_logPath); +} + +void UNertcUserWidget::NativeDestruct() { + ReleaseNertcEngine(); + Super::NativeDestruct(); +} + +void UNertcUserWidget::InitNertcEngine(std::string appKey, std::string logPath) { + nertc_engine_ = nertc::createNERtcEngine(); + + if (!nertc_engine_) + return; + + nertc::NERtcEngineContext context{}; + context.app_key = appKey.c_str(); + //¼صȷYourProjectClass̳IRtcEngineEventHandler + context.event_handler = this; + context.log_dir_path = logPath.c_str(); + context.log_level = kNERtcLogLevelInfo; + + auto ret = nertc_engine_->initialize(context); + if (ret != 0) { + ReleaseNertcEngine(); + return; + } + + //ϷģʽøõƵ ѡ + nertc_engine_->setParameters("{\"sdk.enable.plugin.game.mode\":true}"); + + //ȡƵmanagerڲٿƵ豸 ѡ + nertc_engine_->queryInterface(nertc::kNERtcIIDAudioDeviceManager, (void**)(&audio_device_manager_)); + if (!audio_device_manager_) { + return; + } + + //ý״̬صȷYourProjectClass̳IRtcMediaStatsObserver ѡ + nertc_engine_->setStatsObserver(this); +} +void UNertcUserWidget::ReleaseNertcEngine() { + if (!nertc_engine_) + return; + nertc_engine_->release(); + delete nertc_engine_; + nertc_engine_ = nullptr; +} +void UNertcUserWidget::OnJoinChannelClicked() { + nertc_engine_->joinChannel("", g_channelName.c_str(), g_userID, NERtcJoinChannelOptions{}); +} + +void UNertcUserWidget::OnLeaveChannelClicked() { + nertc_engine_->leaveChannel(); +} + +void UNertcUserWidget::onJoinChannel(channel_id_t cid, nertc::uid_t uid, NERtcErrorCode result, uint64_t elapsed) { + std::cout << "onJoinChannel"< +#include "NertcUserWidget.generated.h" + +/** + * + */ +using namespace nertc; +UCLASS() +class NERTCSAMPLECODE_API UNertcUserWidget : public UUserWidget, public IRtcEngineEventHandler, public IRtcMediaStatsObserver +{ + GENERATED_BODY() +public: + void NativeConstruct() override; + void NativeDestruct() override; + + void InitNertcEngine(std::string appKey, std::string logPath); + void ReleaseNertcEngine(); + + UFUNCTION(BlueprintCallable) + void OnJoinChannelClicked(); + + UFUNCTION(BlueprintCallable) + void OnLeaveChannelClicked(); + +public: + //дonJoinChannel麯joinChannelSDKԶøú֪ͨ + void onJoinChannel(channel_id_t cid, nertc::uid_t uid, NERtcErrorCode result, uint64_t elapsed) override; + //дonConnectionStateChange麯״̬ʱSDKԶøú + void onConnectionStateChange(NERtcConnectionStateType state, NERtcReasonConnectionChangedType reason)override; + //дonLeaveChannel麯뿪SDKԶøú + void onLeaveChannel(NERtcErrorCode result, uint64_t channel_id) override; + //setStatsObserver֮SDKᶨڻصonRtcStatsSDKڲݣCPUʹʵȣ֪ͨ + void onRtcStats(const NERtcStats& stats) override; + +private: + //SDKָ + nertc::IRtcEngineEx* nertc_engine_; + //Ƶ豸ָ + nertc::IAudioDeviceManager* audio_device_manager_; +}; diff --git a/unreal/win/Source/NertcSampleCodeEditor.Target.cs b/unreal/win/Source/NertcSampleCodeEditor.Target.cs new file mode 100644 index 0000000..91b5452 --- /dev/null +++ b/unreal/win/Source/NertcSampleCodeEditor.Target.cs @@ -0,0 +1,14 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; +using System.Collections.Generic; + +public class NertcSampleCodeEditorTarget : TargetRules +{ + public NertcSampleCodeEditorTarget( TargetInfo Target) : base(Target) + { + Type = TargetType.Editor; + DefaultBuildSettings = BuildSettingsVersion.V2; + ExtraModuleNames.AddRange( new string[] { "NertcSampleCode" } ); + } +}