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許可證獲得許可的。