插件来源:heroiclabs/nakama-unreal: Nakama Unreal Client SDK

选nakama框架的重要原因是:不想从零写一个rpc客户端,最好本身就具备聊天功能。从github上下载好之后,插件放到UE工程里编译后,勾选即可。

UE5.7版本编译时可能出现编译失败的情况。解决办法CPP版本设置为CPP20(感谢AI):

//Plugins\Nakama\Source\NakamaUnreal\NakamaUnreal.Build.cs
public class NakamaUnreal : ModuleRules
{
	public NakamaUnreal(ReadOnlyTargetRules Target) : base(Target)
	{
		CppStandard = CppStandardVersion.Cpp20;
		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;

然后打开UE工程找到nakama的关卡demo:Plugins/Nakama/Maps/DemoMap

因为项目以C++为主;UMG蓝图只做显示相关内容。所以我无法使用demo里内置的NakamaDemoController、BPL_Nakama、BPI_Nakama 蓝图实现,必须在已有的PlayerController C++类里面增加等效代码。

在 XXXXXXPlayerController.h

#include "NakamaUnreal/Public/NakamaClient.h"
#include "NakamaUnreal/Public/NakamaRealtimeClient.h"
#include "NakamaUnreal/Public/NakamaSession.h"
#include "NakamaUnreal/Public/NakamaChannelTypes.h"
#include "NakamaUnreal/Public/NakamaGroup.h"
#include "NakamaUnreal/Public/NakamaError.h"
#include "NakamaUnreal/Public/NakamaRtError.h"
#include "NakamaUnreal/Public/NakamaMatch.h"
#include "NakamaUnreal/Public/NakamaNotification.h"


UCLASS()
class XXXXX_API XXXXXXXPlayerController : public ACommonPlayerController
{
	GENERATED_BODY()


// ─── Nakama Integration  start───────────────────────────────────────────────────

UPROPERTY(BlueprintReadOnly, Category = "Zoira|Nakama")
TObjectPtr<UNakamaSession> UserSession;

UPROPERTY(BlueprintReadOnly, Category = "Zoira|Nakama")
TObjectPtr<UNakamaClient> NakamaClient;

UPROPERTY(BlueprintReadOnly, Category = "Zoira|Nakama")
TObjectPtr<UNakamaRealtimeClient> NakamaRealtimeClient;

UPROPERTY(BlueprintReadOnly, Category = "Zoira|Nakama")
FNakamaUserSession CurrentSessionData;

UPROPERTY(BlueprintReadOnly, Category = "Zoira|Nakama")
TArray<FNakamaChannel> JoinedChannels;

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void SetNakamaClient(UNakamaClient* Client);

//UNakamaRealtimeClient
UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void SetNakamaRealtimeClient(UNakamaRealtimeClient* RealtimeClient);

//
UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void SetNakamaUserSession1(UNakamaSession* RealtimeClient);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void AccountChanged(const FNakamaAccount& Account);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void RefreshUserGroups(const FNakamaUserGroupList& UserGroups);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void RemoveTicket(const FString& Ticket);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void AddTicket(const FString& Ticket);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void AddMatch(const FNakamaMatch& Match);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void OpenPrivateMessage(const FNakamaChannelMessage& Message);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void ShowNotification(const FNakamaNotificationList& NotificationList);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void OnRealtimeError(const FNakamaRtError& Error);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void OnError(const FNakamaError& Error);

UFUNCTION(BlueprintCallable, Category = "Zoira|Nakama")
void OnAuthenticated(UNakamaSession* Session);
// ─── Nakama Integration  end───────────────────────────────────────────────────

在XXXXXXPlayerController.cpp  

代码只做了NakamaClient、NakamaRealtimeClient、UserSession变量的存储


// ─────────────────────────────────────────────────────────────────────────────
// Nakama Integration  start
// ─────────────────────────────────────────────────────────────────────────────

void AZoiraPlayerController::SetNakamaClient(UNakamaClient* Client)
{
	this->NakamaClient = Client;
}

void AZoiraPlayerController::SetNakamaRealtimeClient(UNakamaRealtimeClient* InRealtimeClient)
{
	this->NakamaRealtimeClient = InRealtimeClient;
}

void AZoiraPlayerController::SetNakamaUserSession1(UNakamaSession* InSession)
{
	this->UserSession = InSession;
}


void AZoiraPlayerController::AccountChanged(const FNakamaAccount& Account)
{
}

void AZoiraPlayerController::RefreshUserGroups(const FNakamaUserGroupList& UserGroups)
{
}

void AZoiraPlayerController::RemoveTicket(const FString& Ticket)
{
}

void AZoiraPlayerController::AddTicket(const FString& Ticket)
{
}

void AZoiraPlayerController::AddMatch(const FNakamaMatch& Match)
{
}

void AZoiraPlayerController::OpenPrivateMessage(const FNakamaChannelMessage& Message)
{
}

void AZoiraPlayerController::ShowNotification(const FNakamaNotificationList& NotificationList)
{
}

void AZoiraPlayerController::OnRealtimeError(const FNakamaRtError& Error)
{
}

void AZoiraPlayerController::OnError(const FNakamaError& Error)
{
}

void AZoiraPlayerController::OnAuthenticated(UNakamaSession* Session)
{
}

// ─────────────────────────────────────────────────────────────────────────────
// Nakama Integration  end
// ─────────────────────────────────────────────────────────────────────────────

在 XXXX你的工程.Build.cs   增加插件名

PublicDependencyModuleNames.AddRange(
	new string[] { 
		"Core",

        "NakamaUnreal",
    }
);

PrivateDependencyModuleNames.AddRange(
	new string[] {
        "UMG",

        "NakamaUnreal",
    }
);

到现在为止,插件能正常编译通过,现在修改蓝图部分(下面的连接可以复制蓝图)。

nakama-unreal plugin conncect sever posted by zhangkun35268 | blueprintUE | PasteBin For Unreal Engine

通过上面的连接看蓝图即可。
1先通过CreateDefaultClient创建客户端,调用你写的XXXXXXPlayerController中的SetNakamaClient函数保存客户端变量。
2关键步骤是在蓝图中调用你写的XXXXXXPlayerController中的NakamaClient变量,然后拉出线调用AuthenticateEmail蓝图,返回session并获取sessionData,保存userName、Auth Token、Refresh Token(这一步非常重要)。
3调用SetupRealtimeClient然后获得NakamaRealtimeClient(用于websocket聊天功能),然后通过RestoreSession蓝图节点将之前保存的Auth Token、Refresh Token还原为session。通过自己写的SetNakamaUserSession1蓝图函数保存session以备在任何地方使用。

4通过NakamaRealtimeClient变量调用Connect服务器的websocket服务。连接成功后初始化聊天房间。使用NakamaRealtimeClient变量调用JoinChat蓝图节点。chat id填General 类型room

5通过NakamaRealtimeClient变量绑定ChannelMessage事件。收到消息后显示到UMG中。

6使用你写的XXXXXXPlayerController中的NakamaClient和UserSession变量作为参数调用list friends蓝图节点获得历史聊天信息。


进行测试:

.\nakama.exe --database.address "postgres://postgres:postgres@127.0.0.1:5432/nakama?sslmode=disable" --runtime.http_key "zoira_key_123"

用我C++自定义的PlayerController一样是可以的:

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐