UE的MySQL插件实现(登录、注册) 您所在的位置:网站首页 怎么用UltraEdit查看编码 UE的MySQL插件实现(登录、注册)

UE的MySQL插件实现(登录、注册)

2023-06-07 12:14| 来源: 网络整理| 查看: 265

1. 创建插件

在Plugins页面中点击Add,新建一个插件。

在这里插入图片描述

在新建插件中选择Blueprint Library。

在这里插入图片描述

这里填入的信息会相应的在.uplugin中的信息对应。

在这里插入图片描述

在蓝图插件中的函数可以进行同步对应。

UCLASS() class USTHLeariningLoginPluginBPLibrary : public UBlueprintFunctionLibrary { GENERATED_UCLASS_BODY() /**DisplayName是用来指明在蓝图中可调用的函数名称**/ UFUNCTION(BlueprintCallable, meta = (DisplayName = "Execute Sample function", Keywords = "STHLeariningLoginPlugin sample test testing"), Category = "STHLeariningLoginPluginTesting") static float STHLeariningLoginPluginSampleFunction(float Param); };

注意:创建Blueprint Library插件,所有的函数都是static的。相当于一个函数库。

2. 自定义日志

我们创建一个Log文件夹,并新建.h文件,文件编码一定使用UTF-8。

在这里插入图片描述

#pragma once #include "CoreMinimal.h" DEFINE_LOG_CATEGORY_STATIC(LogSTHLogin, Log, All) /** * DeBug信息的几种方式: * 1. 打印到屏幕窗口 * 2. 打印到日志 * 3. 右下角显示一个对话框 * 4. 屏幕中央弹出一个msg */

我们就可以使用UE_Log()中,使用我们创建的这个文件,用来打印日志。

UE_LOG(LogSTHLogin, Display, TEXT("Display")); UE_LOG(LogSTHLogin, Warning, TEXT("Display")); UE_LOG(LogSTHLogin, Error, TEXT("Display"));

日志打印的内容是在/Saved/Logs中,在文件中输入上面的名称,如LogSTHLogin打印内容进行查找。 注意:如果是程序崩溃,也是/Saved文件夹中进行查找。

3. 创建子系统

我们创建一个管理HTTP的子系统,用来实现关于HTTP的相关操作。

在这里插入图片描述

子系统应该继承UGameInstanceSubsystem类和FTickableGameObject类,并重写相关方法。

STHLoginSubsystem.h文件代码如下:

#pragma once #include "CoreMinimal.h" #include "../STHLeariningLoginPluginBPLibrary.h" #include "STHLoginSubsystem.generated.h" UCLASS() class USTHLoginSubsystem : public UGameInstanceSubsystem, public FTickableGameObject { GENERATED_BODY() public: #pragma region GameInstanceSubsystemOverrideFuction // 重写方法 virtual bool ShouldCreateSubsystem(UObject* Outer) const override; virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; #pragma endregion public: #pragma region TickableGameObjectOverrideFuction // 重写方法 virtual void Tick( float DeltaTime ) override; virtual bool IsTickable() const override; virtual TStatId GetStatId() const override; #pragma endregion public: // 注册 bool SubsystemRegister(FString UserName, FString Password, FString PhoneNum, FString EMail, FSTHDelegate RegisterDelegate); // 登录 bool SubsystemLogin(FString UserName, FString Password, FSTHDelegate LoginDelegate); protected: void HttpRegisterIn(); void HttpSignIn(); };

子系统的方法通过BPLibrary调用,BPLibrary.h文件代码如下:

#pragma once #include "Kismet/BlueprintFunctionLibrary.h" #include "STHLeariningLoginPluginBPLibrary.generated.h" // 单播 多播 动态单波 动态单播 DECLARE_DYNAMIC_DELEGATE_TwoParams(FSTHDelegate, bool, str, FString, Message); UCLASS() class USTHLeariningLoginPluginBPLibrary : public UBlueprintFunctionLibrary { GENERATED_UCLASS_BODY() UFUNCTION(BlueprintCallable, meta = (DisplayName = "Execute Register", Keywords = "STHLeariningLoginPlugin Register", WorldContext = "WorldlContextObject"), Category = "STHLeariningLoginPlugin") static bool STHRegister(FString UserName, FString Password, FString PhoneNum, FString EMail, const UObject* WorldlContextObject, FSTHDelegate RegisterDelegate); UFUNCTION(BlueprintCallable, meta = (DisplayName = "Execute Login", Keywords = "STHLeariningLoginPlugin Login", WorldContext = "WorldlContextObject"), Category = "STHLeariningLoginPlugin") static bool STHLogin(FString UserName, FString Password, const UObject* WorldlContextObject, FSTHDelegate LoginDelegate); };

注意: (1)静态方法一定要加上const UObject* WorldlContextObject,这需要在meta中设置WorldContext = “WorldlContextObject”。这是一个用来保存上下文的东西,我们能通过这个拿到它本身。 (2)因为HTTP是异步的,我们不希望运行等待HTTP回调就一直卡在那里,因此我们需要设置动态多播来保证异步,下图是设置委托之后的蓝图。

在这里插入图片描述

BPLibrary.cpp文件代码如下:

#include "STHLeariningLoginPluginBPLibrary.h" #include "STHLeariningLoginPlugin.h" #include "Kismet/GameplayStatics.h" #include "Log/LogSTHLogin.h" #include "LoginCore/STHLoginSubsystem.h" USTHLeariningLoginPluginBPLibrary::USTHLeariningLoginPluginBPLibrary(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } bool USTHLeariningLoginPluginBPLibrary::STHRegister(FString UserName, FString Password, FString PhoneNum, FString EMail, const UObject* WorldlContextObject, FSTHDelegate RegisterDelegate) { if(!WorldlContextObject) { return false; } /**注意:UObject对象都是通过指针来管理生命周期的*/ UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(WorldlContextObject); // 从GEngine中拿到UWorld,再返回UWorld的GetGameInstance USTHLoginSubsystem* STHLoginSubsystem = GameInstance->GetSubsystem(); // 再从GameInstance拿到子系统USTHLoginSubsystem return STHLoginSubsystem->SubsystemRegister(UserName, Password, PhoneNum, EMail, RegisterDelegate); } bool USTHLeariningLoginPluginBPLibrary::STHLogin(FString UserName, FString Password, const UObject* WorldlContextObject, FSTHDelegate LoginDelegate) { if(!WorldlContextObject) { return false; } UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(WorldlContextObject); USTHLoginSubsystem* STHLoginSubsystem = GameInstance->GetSubsystem(); return STHLoginSubsystem->SubsystemLogin(UserName, Password, LoginDelegate); } 4. 读取与使用配置文件

我们使用Project Setting来对自己的配置文件进行创建并且通过读取配置文件来获取到想要的值。

1.创建Project Setting配置项 首先创建配置文件

在这里插入图片描述

LoginSettings.h文件代码如下:

#pragma once #include "CoreMinimal.h" #include "STHLoginSettings.generated.h" UCLASS(Config = STHDataBase, DefaultConfig) class USTHLoginSettings : public UDeveloperSettings { GENERATED_BODY() /** Gets the settings container name for the settings, either Project or Editor */ virtual FName GetContainerName() const override { return TEXT("Project"); // 对应引擎中的 Project Setting }; /** Gets the category for the settings, some high level grouping like, Editor, Engine, Game...etc. */ virtual FName GetCategoryName() const override { return TEXT("STHSetting"); // 对应引擎中 Project Setting 的大模块 }; /** The unique name for your section of settings, uses the class's FName. */ virtual FName GetSectionName() const override { return TEXT("STHDataBaseSetting"); // 对应引擎中的设置项名称 }; public: UPROPERTY(Config, EditAnywhere, BlueprintReadWrite) FString ServerIP = TEXT("127.0.0.1"); // 服务器IP UPROPERTY(Config, EditAnywhere, BlueprintReadWrite) FString ServerPort = TEXT("7000"); // 服务器端口号 };

继承自UDeveloperSettings类并且重写自定义所在的位置,下图我们能在UE的Project Settings中找到我们设置出来的值。

在这里插入图片描述 注意 (1)因为DeverSettings.h在DeverSettings模块中,所以需要在配置文件中加入该模块。

在这里插入图片描述

在这里插入图片描述

(2)当在Project Settings中修改了值,/Config/文件路径中会自动生成并修改对应的配置文件.ini,这样的修改是动态的。

在这里插入图片描述

2.读取配置文件

Subsystem.h文件新增函数

protected: bool LoadServerIPAndPort(FString& ServerIP, FString& ServerPort);

对应实现

bool USTHLoginSubsystem::LoadServerIPAndPort(FString& ServerIP, FString& ServerPort) { FConfigFile DatabaseConfigFile; // ProjectConfigDir()映射到"/Config"路径,读取对应的配置文件 FString Path = FPaths::ProjectConfigDir() / TEXT("DefaultSTHDataBase.ini"); DatabaseConfigFile.Read(Path); bool bServerIP = DatabaseConfigFile.GetString(TEXT("/Script/STHLeariningLoginPlugin.STHLoginSettings"), TEXT("ServerIP"), ServerIP); bool bServerPort = DatabaseConfigFile.GetString(TEXT("/Script/STHLeariningLoginPlugin.STHLoginSettings"), TEXT("ServerPort"), ServerPort); if(bServerIP && bServerPort) { UE_LOG(LogSTHLogin, Display, TEXT("ServerIP: %s"), *ServerIP); UE_LOG(LogSTHLogin, Display, TEXT("ServerPort: %s"), *ServerPort); return true; } UE_LOG(LogSTHLogin, Warning, TEXT("There is no right ServerIP and ServerPort")); return false; }

在SubsystemRegister()和SubsystemLogin()发送HTTP请求时,都用这个函数判断一下IP和端口号是否配置,下图为从配置文件中读取到有效值。

在这里插入图片描述

5. HTTP请求

发送HTTP请求代码如下

void USTHLoginSubsystem::HttpRegisterIn(FString ServerIP, FString ServerPort, FString UserName, FString Password, FString PhoneNum, FString EMail) { UE_LOG(LogSTHLogin, Display, TEXT("STHLoginSubsystem::HttpRegisterIn")); // 1. 创建一个内容体,它是一个字符串 // 1.1 创建一个json对象 TSharedRef RequestObj = MakeShared(); // 1.2 往json对象中输入各种属性 FString InterviewType = "RegisterIn"; RequestObj->SetStringField("InterviewType", InterviewType); RequestObj->SetStringField("UserName", UserName); RequestObj->SetStringField("Password", Password); RequestObj->SetStringField("PhoneName", PhoneNum); RequestObj->SetStringField("Email", EMail); // 1.3 把这个json对象序列化成字符串 FString RequestBody; // 1.3.1 创建一个输入流 TSharedRef Writer = TJsonWriterFactory::Create(&RequestBody); UE_LOG(LogSTHLogin, Display, TEXT("STHLoginSubsystem::%s"), *RequestBody); // 1.3.2 把json对象输入到流里面 FJsonSerializer::Serialize(RequestObj, Writer); /** * 如何反序列化? * 1. 创建一个json的obj对象 * TSharedRef ResponseObj; * 2. 创建一个json的读取流 * TSharedRef Reader = TJsonReaderFactory::Create(RequestBody); * 3. 反序列化 * FJsonSerializer::Deserialize(Reader, ResponseObj); */ // 2. 创建HTTP请求 /** *FHttpRequestRef 为根据不同平台的类型来创建不同的 HTTP *FHttpModule 为处理Http的一个模块,且全局单例 ***/ FHttpRequestRef Request = FHttpModule::Get().CreateRequest(); // 请求完成后,绑定回调函数 Request->OnProcessRequestComplete().BindUObject(this, &USTHLoginSubsystem::OnResponseReceived); // 拼接 http://127.0.0.1:80/Login FString URL = TEXT(""); URL += TEXT("http://"); URL += ServerIP; URL += TEXT(":"); URL += ServerPort; URL += "/Login"; // 由服务器和客户端通信协议确定的 // 设置请求URL Request->SetURL(URL); // 设置请求模式 Get 或 Post Request->SetVerb("Post"); // 设置请求头 Request->SetHeader("Content-Type", "application/json"); // 设置请求内容 Request->SetContentAsString(RequestBody); // 3. 发送请求 Request->ProcessRequest(); }

在配置中加入新的模块

PrivateDependencyModuleNames.AddRange( new string[] { "CoreUObject", "Engine", "Slate", "SlateCore", "DeveloperSettings", "HTTP", "JsonUtilities", "Json", // ... add private dependencies that you statically link with here ... } );


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有