Nakama是一款旨在为现代游戏和应用程序供电的开源服务器。功能包括用户帐户,聊天,社交,媒人,实时多人游戏等等。
该客户端在服务器上实现了完整的API和套接字选项。它用C ++编写,具有最小的依赖性,以支持虚幻4和5。
如果您与客户端遇到任何问题,则可以启用调试日志并打开问题很有用。
完整文档在线-https://heroiclabs.com/docs
该插件也可以用于喜欢C ++或蓝图的程序员。所有变量和功能均暴露于虚幻引擎(Uproperties,USTRUCT,UFUNCTIONS等)使用的类型
该插件分为三个模块,可以根据您的需求拉出。
NakamaUnreal推荐的基于C ++的模块,用于在UNREATENGINE中使用Nakama。这与虚幻的本地类型和ubjject集成在一起。NakamaBlueprints 。NakamaCore适用于从v2.6.0虚幻客户端迁移并想进行最小更改的用户,或者使用我们的低级C ++ API,而没有虚幻类型:(https://github.com/heroiclabs/heroiclabs/nakama-cpp)。由于
NakamaCore使用了预制的库,因此由于Unreal工具链与标准C ++工具链的差异,您可能会遇到构建问题。这就是为什么NakamaUnreal是我们推荐的模块的原因。
在本文档中将客户端称为实时客户端和默认客户端,其中实时客户端是套接字,默认客户端使用REST API与Nakama进行通信。
在与客户端连接之前,您需要设置服务器和数据库。最简单的方法是使用Docker,但请查看其他选项的服务器文档。
要开始在虚幻中使用Nakama,您将需要以下内容:
另外,请确保您的虚幻项目是一个C ++项目。如果仅是蓝图,则可以通过“文件 - >新的C ++类”将新的C ++文件添加到项目中。将其设置为私人,并随心所欲地命名。在项目中使用此文件,可以使虚幻编译插件。
要在您的虚幻项目中使用Nakama,您需要从虚幻市场下载我们的插件,或将您下载的Nakama-Unreal文件复制到适当的地方。做后者:
C:\MyUnrealProject\ )。Plugins文件夹。Nakama文件夹,然后将其放入Plugins夹中可选:您可以将插件放入虚幻的引擎插件文件夹中(例如, C:Program FilesEpic GamesUE_4.26EnginePluginsMarketplace )在多个项目上使用该插件。
在这一点上,您已经完成了。重新启动虚幻。编译内容后,打开编辑 - >插件,然后滚动到底部。如果一切顺利,您应该会看到hermeiclabs.nakama被列为插件。
客户
您必须决定要在哪里创建并保留这些客户的记录。
会议
会话是便携式Uobjects,其中包含会话指针和一个带有会话中实际数据的结构,例如令牌,用户数据,到期信息。会话对象还提供了一些实用程序功能,例如获取特定变量或还原会话。
刻度系统
通常,您必须以C ++为基础处理滴答作用,幸运的是,这是在创建客户端后在此插件的引擎盖下自动完成的。当您创建客户端时,您可以定义一个tick间隔,默认情况下,将其设置为0,这意味着它将勾选每个帧,如果您希望它每50ms勾选为每50ms,则必须将其设置为0.05,以使其每秒勾选为1。
以下是设置默认客户端,进行身份验证,设置实时客户端并加入聊天室的简单示例。在示例中,我们将把所有内容都放在一个空的Aactor类中,该类别位于级别中。
请记住,将Nakamaunreal添加到您的项目build.cs文件下的私人依赖项中。例如:
PrivateDependencyModuleNames . AddRange ( new string [ ] { "NakamaUnreal" } ) ;从标题公共变量开始,我们使用的是一个空白演员,该示例中将放置在场景中。虚幻引擎使用反射系统,该系统提供有关其类的元数据,并允许蓝图/C ++通信,序列化等高级功能。在使用Nakama对象或任何Uobject衍生的类别时,使用虚幻反射系统标记它们至关重要。这是使用宏()和Uproperty()等宏完成的。
UPROPERTY ()
UNakamaClient* NakamaClient;
UPROPERTY ()
UNakamaRealtimeClient* NakamaRealtimeClient;
UPROPERTY ()
UNakamaSession* UserSession;
UFUNCTION ()
void OnAuthenticationSuccess(UNakamaSession* LoginData);
UFUNCTION ()
void OnAuthenticationError( const FNakamaError& Error);
UFUNCTION ()
void OnRealtimeClientConnectSuccess();
UFUNCTION ()
void OnRealtimeClientConnectError( const FNakamaRtError& ErrorData);
// Initialize client and authenticate here
virtual void BeginPlay () override ;例如,如果您希望在蓝图编辑器中使用nakama对象进行操作,则应使用Uproperty()标记它。
UPROPERTY (BlueprintReadWrite, EditAnywhere, Category= " Nakama " )
UNakamaClient* NakamaClientInstance;通过使用blueprintreadwrite指定符,NakamAclientinstance变量在蓝图中既可以阅读又可写。
然后在开始播放中,我们设置默认客户端,身份验证和绑定委托。
// Called when the game starts or when spawned
void AMyActor::BeginPlay ()
{
Super::BeginPlay ();
// Default Client Parameters
FString ServerKey = TEXT ( " defaultkey " );
FString Host = TEXT ( " 127.0.0.1 " );
int32 Port = 7350 ;
bool bUseSSL = false ;
bool bEnableDebug = true ;
// Setup Default Client
NakamaClient = UNakamaClient::CreateDefaultClient (ServerKey, Host, Port, bUseSSL, bEnableDebug);
// Authentication Parameters
FString Email = TEXT ( " [email protected] " );
FString Password = TEXT ( " verysecretpassword " );
FString Username = TEXT ( " debug-user " );
TMap<FString, FString> Variables;
// Setup Delegates of same type and bind them to local functions
FOnAuthUpdate AuthenticationSuccessDelegate;
AuthenticationSuccessDelegate. AddDynamic ( this , &AMyActor::OnAuthenticationSuccess);
FOnError AuthenticationErrorDelegate;
AuthenticationErrorDelegate. AddDynamic ( this , &AMyActor::OnAuthenticationError);
NakamaClient-> AuthenticateEmail (Email, Password, Username, true , Variables, AuthenticationSuccessDelegate, AuthenticationErrorDelegate);
}然后身份验证回调的响应
void AMyActor::OnAuthenticationSuccess (UNakamaSession* LoginData)
{
if (GEngine) GEngine-> AddOnScreenDebugMessage (- 1 , 15 . 0f , FColor::Green, FString::Printf ( TEXT ( " Authenticated As %s " ), *LoginData-> SessionData . Username ));
UserSession = LoginData;
// Setup Delegates of same type and bind them to local functions
FOnRealtimeClientConnected ConnectionSuccessDelegate;
ConnectionSuccessDelegate. AddDynamic ( this , &AMyActor::OnRealtimeClientConnectSuccess);
FOnRealtimeClientConnectionError ConnectionErrorDelegate;
ConnectionErrorDelegate. AddDynamic ( this , &AMyActor::OnRealtimeClientConnectError);
// This is our realtime client (socket) ready to use
NakamaRealtimeClient = NakamaClient-> SetupRealtimeClient ();
// Remember to Connect
bool bCreateStatus = true ;
NakamaRealtimeClient-> Connect (UserSession, bCreateStatus, ConnectionSuccessDelegate, ConnectionErrorDelegate);
}
void AMyActor::OnAuthenticationError ( const FNakamaError& Error)
{
if (GEngine) GEngine-> AddOnScreenDebugMessage (- 1 , 15 . 0f , FColor::Red, FString::Printf ( TEXT ( " Failed to Authenticate: %s " ), *Error. Message ));
}最后,覆盖的实时客户端设置回调,您现在可以使用实时客户端。
void AMyActor::OnRealtimeClientConnectSuccess ()
{
if (GEngine) GEngine-> AddOnScreenDebugMessage (- 1 , 15 . 0f , FColor::Green, FString ( TEXT ( " Socket Setup Success! " )));
// Example of Joining Chat without callbacks
NakamaRealtimeClient-> JoinChat ( " Heroes " , ENakamaChannelType::ROOM, true , false , {}, {});
}
void AMyActor::OnRealtimeClientConnectError ( const FNakamaRtError& ErrorData)
{
if (GEngine) GEngine-> AddOnScreenDebugMessage (- 1 , 15 . 0f , FColor::Red, FString ( TEXT ( " Socket Setup Failed! " )));
}如果您正确设置所有内容,请创建该演员的蓝图版本,然后将其放置在屏幕上的消息中,说明您已验证您已验证,用户名,然后是插座连接的消息。
最新的Nakama虚幻发布具有灵活性,可以使用Dynamic Multicast Delegates或Lambdas (TFunctions)来处理功能和事件。这是有关如何使用它们的简短比较和指南:
AddDynamic绑定。将您首选的回调类型( delegate或lambda )提供到相关Nakama功能的Success和Error参数中。
这是使用lambdas作为delegates的替代方案的演示:
// Define success callback with a lambda
auto successCallback = [&](UNakamaSession* session)
{
UE_LOG (LogTemp, Warning, TEXT ( " Session Token: %s " ), *Session-> GetAuthToken ());
UE_LOG (LogTemp, Warning, TEXT ( " Username: %s " ), *Session-> GetUsername ());
};
// Define error callback with a lambda
auto errorCallback = [&]( const FNakamaError& Error)
{
UE_LOG (LogTemp, Warning, TEXT ( " Error Code: %d " ), Error. Code );
};
// Execute the AuthenticateEmail function with lambdas
Client-> AuthenticateEmail (TEXT( " [email protected] " ), TEXT( " verysecretpassword " ), TEXT( " debug-user " ), true, {}, successCallback, errorCallback);在初始化您的实时客户端时,必须为关键游戏中的重要事件建立事件听众,从渠道消息和通知到派对互动。 Nakama虚幻,通过允许Lambdas和代表为此目的提供灵活性。
// Start by creating a Realtime Client:
UNakamaRealtimeClient* Socket = NakamaClient-> SetupRealtimeClient ();
// When using delegates, you need to declare functions that match the delegate's signature:
Socket->ChannelMessageReceived.AddDynamic( this , &ANakamaActor::OnChannelMessageReceived);
Socket->NotificationReceived.AddDynamic( this , &ANakamaActor::OnNotificationReceived);
// Lambdas offer a concise way to define event handlers directly in-line:
// Note: A lambda can be bound only once.
Socket-> SetChannelMessageCallback ( []( const FNakamaChannelMessage& ChannelMessage)
{
UE_LOG (LogTemp, Warning, TEXT ( " Channel Message: %s " ), *ChannelMessage. Content );
});
Socket-> SetNotificationsCallback ( []( const FNakamaNotificationList& NotificationList)
{
UE_LOG (LogTemp, Warning, TEXT ( " Notifications: %d " ), NotificationList. Notifications . Num ());
for ( auto & Notification : NotificationList. Notifications )
{
UE_LOG (LogTemp, Warning, TEXT ( " Notification: %s " ), *Notification. Content );
}
});
// Establish a connection to start receiving events.
// Optional success and error callbacks (either lambdas or delegates) can be provided:
Socket-> Connect (Session, true );功能实现可能看起来像这样:
void ANakamaActor::OnChannelMessageReceived ( const FNakamaChannelMessage& ChannelMessage)
{
UE_LOG (LogTemp, Warning, TEXT ( " Channel Message: %s " ), *ChannelMessage. Content );
}
void ANakamaActor::OnNotificationReceived ( const FNakamaNotificationList& Notifications)
{
for ( auto NotificationData : Notifications. Notifications )
{
UE_LOG (LogTemp, Warning, TEXT ( " Notification: %s " ), *NotificationData. Content );
}
}NakamaBlueprints入门在本节中,您将学习如何手动创建和管理该插件提供的Nakama客户端,完全在蓝图中。
它取决于您要在哪里创建和存储对客户的参考,这可以在任何演员,组件,角色,游戏机等中完成。将客户端放在玩家控制器或游戏实例中。
首先添加nakama库的零件的创建默认客户端节点。

最好将客户推广到变量,以便您可以在蓝图图中访问其他位置。

现在,您可以使用许多提供的Nakama身份验证类型之一进行身份验证,在此示例中,我们将使用电子邮件和密码进行身份验证,通常您会设置一个窗口小部件蓝图并将输入从UI传递到身份验证节点,并通过按登录按钮来验证。

如您所见,这将返回将传递到其他功能的会话对象,请确保促进会话对象以供以后使用。使用此插件,您可能会有多个会话,每个不真实的实例可以保留记录并决定如何使用会话。变量引脚也需要连接,但是如果您不想使用自定义变量,则可以将字符串映射留为空。

创建默认客户端后,您将能够设置一个或多个与服务器交互的实时客户端(套接字)。
从您之前创建的NakamaClient中拖出,并调用设置实时客户端函数。

请记住,要早些时候从成功的身份验证中提供用户会话,然后将自定义事件绑定到成功和错误回调。实时客户端将从该节点返回,并准备与Nakama服务器通信。您现在可以使用聊天和媒人等功能。

创建您的实时客户端后,您准备好绑定到其“事件”

设置特定的侦听器后,您可以绑定到回调。

创建一个自定义事件,并给它一个有意义的名称。

在下面的示例中,我们为通知设置了一个侦听器,然后绑定到事件,循环绕通知并将其打印为屏幕上的调试字符串。

在下一个示例中,我们会收听Matchmaker匹配事件,然后通过与返回的令牌一起加入火柴来绑定并处理响应,然后返回匹配项,包括匹配ID,Presence,标签等。

如前所述,当您使用Nakama进行身份验证时,您会收到一个会话对象,您应该将其存储在蓝图中易于访问的某个地方,因为此插件中的许多节点都需要一个会话对象作为函数的输入。
会话对象包含实际的会话参考,还包含具有蓝图中可读数据的结构。从会话中拖出并获取会话数据。

还有一些其他会话管理方法,例如恢复会话并检查会话是否过期

建议从会话中存储验证令牌,并在启动时检查是否过期。如果令牌已过期,则必须重新验证。令牌的到期时间可以作为服务器中的设置更改。
客户端为游戏服务器的各种功能提供了许多内置API。可以使用异步方法访问这些方法,该方法返回成功和错误回调。他们还可以将自定义逻辑称为服务器上的RPC函数。所有请求均以授权客户端的会话对象发送。

RPC节点可用于在服务器上运行特定功能,有效负载应为JSON格式。

向前迈进,您应该准备好使用Nakama的所有功能来为您的Awesome Unreal Engine构建的游戏或应用程序供电,该游戏完全在蓝图中完成。请参阅https://heroiclabs.com/docs的官方文档,即使在C ++中描述了一些文档,相同的核心功能适用于蓝图实现。
光标用于将分页功能添加到某些节点,例如朋友列表和排行榜记录。当有更多数据要检索时,将在成功回调中返回光标字符串。您可以将此光标存储为字符串,然后以后使用它,例如当一个人单击“更多”按钮或立即使用它来获取更多数据时。查看下面的示例。

默认情况下,日志记录被禁用。但是,创建客户端时,您可以选择Enable Debug ,允许使用调试日志类别编写日志。您也可以手动控制记录。
从蓝图启用记录: 
从C ++启用记录
要启用登录C ++,请包括以下标头文件:
# include " NakamaLogger.h "随后,要切换日志记录,请使用:
UNakamaLogger::EnableLogging ( true );要设置日志级别,请使用:
UNakamaLogger::SetLogLevel (ENakamaLogLevel::Debug);日志类别如下:
Debug写所有日志。
Info以Info , Warn , Error和Fatal记录级别写入日志。
Warn以Warn , Error和Fatal记录级别写日志。
Error写入Error和Fatal记录级别的日志。
Fatal文字仅写着Fatal记录水平的日志。
该存储库包括一个测试套件,用于测试Nakama的各种功能,用于虚幻,可以在编辑器中,从命令行中运行测试,并且如果您想在蓝图中运行相同的测试,则具有一个带有单独文档的BlueprintsTest项目。
Nakama插件添加到项目中的Plugins目录Edit -> Plugins下启用Functional Testing Editor插件,然后重新启动编辑器Tool -> TestAutomationStart Tests
测试可以在打包和使用虚幻编辑器的命令行版本中进行。
对于所有基于命令行的测试,从执行以下步骤开始:
Nakama插件放入项目中的Plugins目录中Nakama插件Windows-编辑器:
要构建测试,请运行:
" <Path_To_Unreal_Engine>EngineBuildBatchFilesBuild.bat " < YourProjectName > Editor Win64 Development -Project= " <Path_To_Your_Project><YourProjectName>.uproject "要运行测试,请运行:
" <Path_To_Unreal_Engine>EngineBinariesWin64UnrealEditor-Cmd.exe " " <Path_To_Your_Project><YourProjectName>.uproject " -ExecCmds= " Automation RunTests <YourTestName> " -log -NullRHI -verbose -unattended -ReportOutputPath= " <Path_To_Store_Report> "如果要运行所有测试,请用Nakama.Base替换<YourTestName> ,如果指定ReportOutputPath ,您将收到概述json logFile,则将存储在Saved/Logs目录中。
窗户 - 包装:
要构建测试,请运行:
" <Path_To_Unreal_Engine>/Engine/Build/BatchFiles/RunUAT.sh " BuildCookRun -targetconfig=Debug -project= " <Path_To_Your_Project><YourProjectName>.uproject " -noP4 -installed -utf8output -build -cook -stage -package -verbose -stdout -nohostplatform -useshellexecute要运行测试,请运行:
./ < YourProjectName > /Saved/StagedBuilds/Windows/ < YourProjectName > .exe -nullrhi -verbose -ExecCmds= " Automation RunTests Nakama.Base " -logMac-包装:
要构建测试,请运行:
" <Path_To_Unreal_Engine>/Engine/Build/BatchFiles/RunUAT.sh " BuildCookRun -project= " <Path_To_Your_Project><YourProjectName>.uproject " -targetConfig=Debug -noP4 -platform=Mac -Architecture_Mac=arm64 -targetconfig=Debug -installed -unrealexe=UnrealEditor -utf8output -build -cook -stage -package -verbose要运行测试,请运行:
./ < YourProjectName > /Binaries/Mac/ < YourProjectName > .app/Contents/MacOS/ < YourProjectName > -nullrhi -stdout -forcelogflush -ExecCmds= " Automation RunTests Nakama.Base " -logLinux-包装:
要构建测试,请运行:
" <Path_To_Unreal_Engine>/Engine/Build/BatchFiles/RunUAT.sh " BuildCookRun -project= " <Path_To_Your_Project><YourProjectName>.uproject " -clientconfig=Test -noP4 -platform=Linux -targetconfig=Debug -installed -utf8output -build -cook -stage -package -verbose要运行测试,请运行:
./ < YourProjectName > /Binaries/Linux/ < YourProjectName > -nullrhi -stdout -forcelogflush -ExecCmds= " Automation RunTests Nakama.Base " -log传递参数
可以以命令行参数传递诸如主机名,端口和服务器密钥之类的参数,这是一个示例:
-hostname= " 127.0.0.1 " -port=7350 -serverkey= " defaultkey " -serverhttpkey= " defaulthttpkey " -timeout=45 -useSSL该插件的某些功能取决于JSON,例如发送聊天消息和使用存储对象存储数据。因此,建议如果使用纯蓝图,您可以找到一个可以构建和解析JSON字符串(例如Varest)的插件。
当您在编辑器中开发时,您可以使用PIE(在编辑器中播放)运行多个虚幻实例,并能够使用单独的帐户进行身份验证,这在测试需要多个播放器的功能时非常有用,例如CHAT,实时多人游戏,对接游戏等。
在本文档的安装部分中,我们将C ++添加到我们的项目中,这只是为了编译插件,您仍然只能使用蓝图。
该插件提供的是一个示例项目,该项目以纯蓝图开发,该项目几乎展示了所有Nakama核心功能。



开发路线图作为GitHub问题进行管理,并欢迎拉动请求。如果您有兴趣增强代码,请打开一个问题,讨论更改或在社区论坛中进行讨论。
虚幻模块基于一般C ++ SDK
在将其放置在NakamaCore/libnakama目录中之前,我们使用VCPKG将Nakama-SDK安装为任何给定工具链:
ARM64-OSX: vcpkg install --overlay-triplets=./triplets --host-triplet=arm64-osx-release-heroic --triplet=arm64-osx-release-heroic
X64-WINDOWS: vcpkg install --overlay-triplets=./triplets --host-triplet=x64-windows-heroic --triplet=x64-windows-heroic
ARM64-WINDOWS: vcpkg install --overlay-triplets=./triplets --host-triplet=arm64-windows-heroic --triplet=arm64-windows-heroic
X64-Linux: vcpkg install --overlay-triplets=./triplets --host-triplet=x64-linux-release-heroic --triplet=x64-linux-release-heroic
然后从vcpkg_install中复制库中的库中的libnakama目录,并将其标题复制到NakamaCore/Public/nakama-cpp 。
然后,您可以从命令行中编译插件,如果您通过Epic Launcher插入编辑器,则传递-Rocket标志。但是,至少对于运行命令行,不建议使用Epic Launcher分布。
视窗:
${UNREAL_ENGINE} /Engine/Build/BatchFiles/RunUAT.sh BuildPlugin -NoHostPlatform -Plugin= " ${NAKAMA_UNREAL} /Nakama/Nakama.uplugin " -TargetPlatforms=Win64 -package= ${NAKAMA_UNREAL} /Out/Nakama苹果:
${UNREAL_ENGINE} /Engine/Build/BatchFiles/RunUAT.sh BuildPlugin -NoHostPlatform -Plugin= " ${NAKAMA_UNREAL} /Nakama/Nakama.uplugin " -TargetPlatforms=Mac -package= ${NAKAMA_UNREAL} /Out/Nakama -Architecture_Mac=arm64对于iOS,将iOS传递给TargetPlatforms 。
要查看自动化命令的完整列表,请运行:
${UNREAL_ENGINE}/Engine/Build/BatchFiles/RunUAT.sh -List
Linux:
${UNREAL_ENGINE}/Engine/Build/BatchFiles/RunUAT.sh BuildPlugin -NoHostPlatform -Plugin="${NAKAMA_UNREAL}/Nakama/Nakama.uplugin" -TargetPlatforms=Linux -package=${NAKAMA_UNREAL}/Out/Nakama
您可以在此处找到Nakama虚幻客户指南。
该项目是根据Apache-2许可证获得许可的。