寫在前面
Hello,小伙伴們中秋節(jié)快樂呀不铆。我又給大家?guī)碜钚乱黄诘拈_發(fā)日志了蝌焚。這一期我們要搞定的是UE4和KBEngine之間的,前后端通信誓斥。并且我們嘗試理清楚登錄過程中的邏輯只洒。為下一步的開發(fā)做好準備工作。廢話不多說我們開始吧劳坑!
這篇文章的視頻版在這里:
====
====
交流QQ群:872537977
項目地址github:
https://github.com/Liweimin0512/uRPG
準備工作
上一期的開發(fā)日志中毕谴,我們已經(jīng)順利地啟動了服務器。
這一期最開始我們要做的就是新建一個客戶端項目,這次我們直接安裝第三人稱C++項目析珊。并且將這個項目存在了這里:
然后我們要搞定KBEngine的客戶端插件,我們可以參考官方的UE4Demo蔑穴,項目地址:
https://github.com/kbengine/kbengine_ue4_demo
將其中的插件拷貝到我們的客戶端項目下忠寻,或者直接下載官方的插件項目也是一樣的:
https://github.com/kbengine/kbengine_ue4_plugins
安裝插件
關(guān)于UE4插件的安裝這里我多介紹兩句,雖然是很簡單的知識:
首先就是要在這里新建一個必須命名為Plugins的文件夾存和,并將相關(guān)的插件放入這個文件夾奕剃。在之后,要在UE4項目專門管理項目結(jié)構(gòu)的CS文件中添加相應的配置捐腿。
這個文件的名稱是*.Build.cs纵朋,如上圖所示,在 PublicDependencyModuleNames中添加你的插件即可茄袖。
這里我們需要用到KBEngine的客戶端SDK自動生成工具操软。如下圖所示:
箭頭位置就是客戶端SDK生成工具的批處理文件,運行之后會同時生成UE4和Unity兩款引擎的插件宪祥。將UE4的復制到我們上文中提到的地址聂薪。
然后我們嘗試編譯運行項目,OK蝗羊,沒什么問題藏澳。那么這一步可以先告一段落了。
登錄流程
這里我花了一些時間搞清楚KBEngine的登錄邏輯究竟是怎樣的耀找。這方面主要是通過看官方文檔以及源代碼來研究的翔悠。其實也不是很難。但是理解清楚還是要花些時間野芒。我這里將思路整理出來給大家分享下蓄愁,希望能給大家節(jié)省點時間。
官方說引擎和客戶端的通信狞悲,絕大多數(shù)是依賴于Entity的涝登。而在登錄這個環(huán)境就是絕大多數(shù)之外的。因為在登錄時我們還沒有建立客戶端代理類效诅。所以這個過程更像是web應用的收發(fā)模式胀滚。簡單說就是客戶端發(fā)起請求,服務器接收到請求并處理后將結(jié)果通過回調(diào)函數(shù)的方式返回給客戶端乱投⊙柿客戶端依靠返回的消息在界面上做出相應的展示即可。
只不過這過程中涉及到一層服務器引擎為我們生成的客戶端SDK戚炫,讓事情變得簡單多了剑刑。我們只需要處理好客戶端和SDK之間的事件即可。而不是直接與服務器進行交互。舉個例子施掏,我們把Login請求發(fā)送給SDK钮惠,SDK進行一系列底層運算之后,發(fā)送給服務器七芭。
而服務器又是怎么做的呢素挽?它通過LoginApp、LoginAppScript和dbmgr層層回調(diào)狸驳,在每一層回調(diào)中我們都可以進行相應的操作预明。當Login操作成功后,引擎才會通知BaseAppMgr耙箍,它會為我們分配一個BaseApp撰糠。之后的事情就是我們和這個App之間的通信了。而這種通信依賴于一個名為Account的特殊Entity辩昆。官方稱之為用戶入口實體阅酪。
此外,查看官方Demo和官方文檔發(fā)現(xiàn)我們需要創(chuàng)建一個Actor并且添加一個KBEMain的組件汁针。命名隨意遮斥,官方命名為ClientApp我決定挺準確的就跟著這么命名吧。KBEMain這個組件就是我們前后端通信的橋梁了扇丛。我們需要格外注意术吗。
客戶端目錄結(jié)構(gòu)
首先我們在content 根目錄下新建一個文件夾,命名為MMORPG
帆精。我們給它標記一個黃色较屿。這樣更顯眼一些。
我們點進來卓练,創(chuàng)建三個文件夾隘蝎。分別命名為Levels(關(guān)卡)、Buleprints(藍圖)和Widgets(界面)襟企。如下圖所示:
登錄場景和登錄界面
在魔獸世界中嘱么,我們玩家從打開游戲到進入游戲世界經(jīng)歷的過程:
登錄界面 -> 角色選擇界面 -> 游戲主場景
所以這一期我們先來完成登錄界面的制作。首先新建一個關(guān)卡命名為Map_Login顽悼。然后新建一個Widget曼振,命名為UMG_LoginMain。配套的也新建一個GameMode藍圖Bp_LoginGameMode蔚龙。
這里補充說明一下冰评,這里的GameMode需要繼承自C++的GameMode。我這里命名為RPGLoginGameMode木羹。參考官方Demo的寫法甲雅〗馑铮考慮到我們這個游戲至少會有三個GameMode,分別是Login,Select和Main(對應3個場景)。所以我們在這三個GameMode上再抽象出一個RPGGameModeBase的類。并將一些通用的方法放在這個類中。
然后我們的藍圖Bp_LoginGameMode再繼承自這個RPGLoginGameMode即可:
之后我們將Login的關(guān)卡GameMode設置為這個GameMode即可:
再說回我們的UMG_LoginMain ,這里我們先用幾個簡單的控件實現(xiàn)效果:
這個界面十分簡單吩谦,這里就不多提了,簡單說就是兩個文本輸入框和兩個按鈕而已。重點的是按鈕交互響應的部分。
當BT_login被點擊時,我們直接調(diào)用ClientApp中KBMain組建的Login方法忌穿,并將UserName和Password傳給它抒寂。就算是搞定了。此外這里還允許我們將一些自定義數(shù)據(jù)傳給后端掠剑,沒傳會報錯屈芜。所以這里我們對應新建一個變量。在事件開始時候清空變量即可朴译。這樣就確保這個數(shù)據(jù)是我們事件內(nèi)部的數(shù)據(jù)(沒有為空)了井佑。
這里補充一下ClientApp這個變量,我們在Construct事件中通過查找Class的方式找到所有ClientApp的實例眠寿,因為我們知道這個Actor理論上應該是單例躬翁。所以我們直接取第一個,然后將其存為變量盯拱,持有盒发。方便之后調(diào)用。
登錄界面是我們登錄關(guān)卡的主界面狡逢,因此我們在Bp_LoginGameMode中將它直接創(chuàng)建出來宁舰,并且為了方便點擊我們還要將鼠標顯示出來,方法很簡單奢浑,相信看過我之前的開發(fā)日志的小伙伴都應該清楚怎么操作了:
登錄響應
當我們調(diào)用了Login方法蛮艰,經(jīng)過一連串的事件通信,最后會傳給后端雀彼。后端再經(jīng)過一連串處理后壤蚜,會給與我們響應。這個相應通過SDK的包裝徊哑,依然是以事件的形式傳遞給我們前端的仍律。還記得我們前文中創(chuàng)建的RPGGameModeBase和LoginGameModeBase這兩個C++類么?這里我們著重研究下這兩個類实柠。
這兩個類水泉,我們臨摹KBEngine的官方Demo。來看看有哪些發(fā)現(xiàn),首先看RPGGameModeBase.h這個頭文件草则,可以看到最主要的是installEvents這個方法钢拧,官方注釋是“安裝登錄時需要堅挺的KBE事件”,之后便是一些事件的聲明:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Scripts/LogicEvents.h"
#include "GameFramework/GameModeBase.h"
#include "RPGGameModeBase.generated.h"
/**
*
*/
UCLASS() class CLIENT_API ARPGGameModeBase : public AGameModeBase {
GENERATED_UCLASS_BODY()
public: //一些集成的方法這里不多提
// ...
/*
安裝登陸時需要監(jiān)聽的KBE事件
*/
virtual void installEvents();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = KBEngine)
bool startRelogin;
UFUNCTION(BlueprintCallable, Category = KBEngine)
void fire(const FString& eventName, UKBEventData* pEventData);
/* KBE事件
玩家被踢出服務器
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "KBEngine")
void onKicked(const UKBEventData* pEventData);
/* KBE事件
*/
//后面是一些事件的聲明炕横,這里暫且不表
};
那我們看看installEvents是如何實現(xiàn)的:
void ARPGGameModeBase::installEvents() {
// common
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onKicked, onKicked);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onDisconnected, onDisconnected);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onConnectionState, onConnectionState);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onReloginBaseappSuccessfully,onReloginBaseappSuccessfully);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onReloginBaseappFailed,onReloginBaseappFailed);
}
這些具體事件我們暫時不了解含義源内,沒關(guān)系。我們現(xiàn)在至少清楚KBEngine引擎是通過在installEvents這個方法中使用KBENGINE_REGISTER_EVENT注冊事件的份殿。這也是官方所說的我們客戶端和客戶端SDK之間事件通信的起點膜钓。在我們注冊之后,SDK接收到來自服務器的消息后就可以通過事件的形式回調(diào)我們對應的客戶端方法卿嘲。然后我們就可以在回調(diào)函數(shù)中進行我們需要的操作了颂斜。
不過這里只有一些通用的事件,我們還是要看更具體的LoginGameModeBase中是什么樣的拾枣,來一起看看其中注冊了哪些事件吧:
void ALoginGameModeBase::installEvents() {
Super::installEvents(); // login
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onCreateAccountResult,onCreateAccountRes
ult);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onLoginFailed,onLoginFailed);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onVersionNotMatch,onVersionNotMatch);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onScriptVersionNotMatch,onScriptVersionNotMatch);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onLoginBaseappFailed,onLoginBaseappFailed);
KBENGINE_REGISTER_EVENT(KBEngine::KBEventTypes::onLoginBaseapp, onLoginBaseapp);
KBENGINE_REGISTER_EVENT("onLoginSuccessfully", onLoginSuccessfully);
KBENGINE_REGISTER_EVENT("Loginapp_importClientMessages", Loginapp_importClientMessages);
KBENGINE_REGISTER_EVENT("Baseapp_importClientMessages", Baseapp_importClientMessages);
KBENGINE_REGISTER_EVENT("Baseapp_importClientEntityDef", Baseapp_importClientEntityDef);
}
果然沃疮,這里有我們最需要的登錄成功和登陸失敗事件。由于我們的Bp_LoginGameMode藍圖繼承自LoginGameModeBase梅肤,所以這里可以找到相關(guān)事件:
成功和失敗事件都很簡單司蔬,成功時我們直接跳轉(zhuǎn)到Map_SelectAvatar即可。失敗的話我們就將報錯信息打印出來即可姨蝴。如下圖所示:
驗證
看起來似乎一切都準備好了俊啼,我們來啟動服務器和客戶端驗證一下。
提前說明一下左医,如果我們客戶端成功登錄吨些,按照流程是會跳轉(zhuǎn)到選擇角色關(guān)卡的。這里要將Map_SelectAvatar準備好炒辉。并且最好將其他情況的回調(diào)事件中也都PrintString中打印出來豪墅。這樣方便我們調(diào)試。我這里圖塊黔寇,為了讓咱們這期的開發(fā)日志看起來簡單些偶器。這里就沒做多余的操作。
運行前后端缝裤,隨便輸入賬戶名和密碼(服務端和客戶端都沒有做驗證)屏轰,點擊登錄按鈕,順利的跳轉(zhuǎn)到Map_SelectAvatar關(guān)卡了憋飞!很好霎苗,我們這一期的開發(fā)日志算是完美的完成了!