ue4账号注册不了_【UE4实现登录注册功能】-开发者专栏-【游戏蛮牛】-游戏出海,ar增强现实,虚拟现实,unity3d,unity3d教程下载首选u3d,unity3d社区 - Powered ...
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本节主要讲解游戏的起始页,登录页,注册页的实现。主要讲解的知识点是C++如何使用UMG做界面开发和UE4如何实现HTTP通讯及JSON的序列化和反序列化。视频教程链接可到蛮牛教育观看,详情链接点击:无尽之刃·文明1、起始页开发
1、创建蓝图版UserWidget
首先创建好UI目录,把UI素材导入到目录中。
创建起始页蓝图版的UserWidget,按照上述成品图设计即可。包含的元素如下:背景图片
Logo图片
开始游戏按钮
注册账号按钮
退出游戏按钮
版本信息文本
注意事项:设计UMG界面时特别需要注意锚点的使用以及布局面板的使用,起始页面使用的是
VerticalPanel对右面的Logo到版本信息进行了垂直布局。2、创建C++版UserWidget
首先我们要在Build.cs里面把UMG和Slate配置上去。
创建蓝图UserWidget的父类,让上面的蓝图继承之。因为我们要获取起始页面具体的按钮的引用来进一步对UMG的Widget进行操作。
根据上面的界面设计,我们在头文件中创建了三个UButton,分别表示开始游戏、注册游戏、退出游戏。我们希望这三个成员变量在子类蓝图UMG创建时自动初始化,因此我们重写UserWidget的Initialize()方法,在蓝图UMG初始化时自动初始化父类(UStartUserWidget)的三个按钮成员变量即可。
退出游戏按钮的事件非常的简单,因此我们这里在父类实现即可。添加OnClicked事件并实现退出游戏的逻辑。
综上,我们可以看出UMG的基本的开发思路,首先要设计好要展示的蓝图版的UMG,然后创建C++版的UserWidget,其成员变量/方法应是关于蓝图版的UMG的数据,以方便来使用蓝图版的UMG里面定义的控件。然后回到蓝图版的UMG让其父类继承之。
起始页头文件(StartUserWidget.h)/**
* 游戏开始界面
*/
UCLASS()
class INFINITYBLADE_API UStartUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
/** 开始游戏按钮 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UButton* StartBtn;
/** 注册游戏按钮 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UButton* RegisterBtn;
/** 退出游戏按钮 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UButton* ExitBtn;
public:
/** 创建UserWidget对象后执行的生命周期方法 */
virtual bool Initialize() override;
/** 初始化控件引用 */
void Init();
/** 退出游戏按钮点击事件 */
UFUNCTION()
void ExitBtnClickedEvent();
};
起始页cpp文件(StartUserWidget.cpp)#include "StartUserWidget.h"
/** 创建UserWidget对象后执行的生命周期方法 */
bool UStartUserWidget::Initialize()
{
if (!Super::Initialize())
{
return false;
}
/** 初始化控件的引用 */
Init();
return true;
}
/** 初始化控件引用 */
void UStartUserWidget::Init()
{
/** 初始化游戏开始按钮 */
StartBtn = Cast(GetWidgetFromName(TEXT("Button_Start")));
/** 初始化游戏注册按钮 */
RegisterBtn = Cast(GetWidgetFromName(TEXT("Button_Register")));
/** 初始化游戏退出按钮 */
ExitBtn = Cast(GetWidgetFromName(TEXT("Button_Exit")));
/** 设置退出游戏按钮的点击事件 */
ExitBtn->OnClicked.AddDynamic(this, &UStartUserWidget::ExitBtnClickedEvent);
}
/** 退出游戏按钮点击事件 */
void UStartUserWidget::ExitBtnClickedEvent()
{
/** 退出游戏 */
UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit);
}3、事件的监听
上面我们已经把退出游戏按钮的点击事件实现了,还有开始游戏和注册账号两个按钮的事件没有实现,此时,我们考虑一下MVC的设计模式以及高内聚低耦合的模式,我们应该把那两个按钮的事件放在哪里呢?
首先肯定是不能放到自己写的C++父类里面的,如果放在里面的话,我们首先要获取开始游戏页面和注册游戏页面的控件引用,这样就不符合低耦合的概念了。所以这里考虑UE4提供的Gameplay框架,我们首先是考虑放到了GameMode这个类里面。下面是游戏首页关卡的游戏模式类,该类里面拥有我们对于UI的处理逻辑。我们看到还有两个成员变量分别是登录页面和注册页面的UI,我们现在先暂时不考虑,下面会讲解这两个页面的开发。
我们首先看一下起始页面UI的初始化、开始游戏按钮的回调事件和注册游戏按钮的回调事件。初始化UStartUserWidget对象这里采用的静态加载LoadClass()方法,我们也可以创建游戏模式的蓝图,使用TSubclassOf的方式来加载,这里技术细节不具体赘述了。初始化完成后把该UMG添加到Viewport即可。
开始游戏按钮和注册游戏按钮只需要添加OnClicked事件即可。在这两个游戏按钮的点击事件上,我们动态的切换Viewport展示的UMG即可。
至此,我们已经把游戏起始页的基本功能完成了,这里只是粗略的赘述了一下,如果想更了解细节可以看源代码来自己手动实现。
首页游戏关卡的游戏模式类的头文件:EmptyGameMode.h/**
* 初始化关卡游戏模式
*/
UCLASS()
class INFINITYBLADE_API AEmptyGameMode : public AGameMode
{
GENERATED_BODY()
public:
/** 起始页面UI */
UPROPERTY()
UStartUserWidget* StartUI;
/** 登录页面UI */
UPROPERTY()
ULoginUserWidget* LoginUI;
/** 注册页面UI */
UPROPERTY()
URegisterUserWidget* RegisterUI;
public:
/** 游戏开始调用的方法 */
virtual void BeginPlay() override;
/** 开始游戏按钮回调事件 */
UFUNCTION()
void StartBtnClickedEvent();
/** 注册按钮回调事件 */
UFUNCTION()
void RegisterBtnClickedEvent();
/** 登录页返回按钮回调事件 */
UFUNCTION()
void LoginBackBtnClickedEvent();
/** 注册页返回按钮回调事件 */
UFUNCTION()
void RegisterBackBtnClickedEvent();
};
```
首页游戏关卡的游戏模式类cpp文件:EmptyGameMode.cpp
``` C++
#include "EmptyGameMode.h"
/** 游戏开始调用的方法 */
void AEmptyGameMode::BeginPlay()
{
/** 初始化起始页UI */
StartUI = CreateWidget(GetGameInstance(), LoadClass(nullptr, TEXT("WidgetBlueprint'/Game/UI/Start/UI_Start.UI_Start_C'")));
/** 设置开始游戏按钮的点击事件 */
StartUI->StartBtn->OnClicked.AddDynamic(this, &AEmptyGameMode::StartBtnClickedEvent);
/** 设置注册按钮的点击事件 */
StartUI->RegisterBtn->OnClicked.AddDynamic(this, &AEmptyGameMode::RegisterBtnClickedEvent);
/**初始化登录页UI */
LoginUI = CreateWidget(GetGameInstance(), LoadClass(nullptr, TEXT("WidgetBlueprint'/Game/UI/Login/UI_Login.UI_Login_C'")));
/** 设置返回按钮的点击事件 */
LoginUI->BackBtn->OnClicked.AddDynamic(this, &AEmptyGameMode::LoginBackBtnClickedEvent);
/**初始化注册页UI */
RegisterUI = CreateWidget(GetGameInstance(), LoadClass(nullptr, TEXT("WidgetBlueprint'/Game/UI/Register/UI_Register.UI_Register_C'")));
/** 设置返回按钮的点击事件 */
RegisterUI->BackBtn->OnClicked.AddDynamic(this, &AEmptyGameMode::RegisterBackBtnClickedEvent);
/** 添加起始页到视口 */
StartUI->AddToViewport();
}
/** 开始游戏按钮回调事件 */
void AEmptyGameMode::StartBtnClickedEvent()
{
/** 移除起始页UI */
StartUI->RemoveFromViewport();
/** 添加登录页UI到视口 */
LoginUI->AddToViewport();
}
/** 注册按钮回调事件 */
void AEmptyGameMode::RegisterBtnClickedEvent()
{
/** 移除起始页UI */
StartUI->RemoveFromViewport();
/** 添加注册页UI到视口 */
RegisterUI->AddToViewport();
}
/** 登录页返回按钮回调事件 */
void AEmptyGameMode::LoginBackBtnClickedEvent()
{
/** 移除登录页UI */
LoginUI->RemoveFromViewport();
/** 添加起始页UI到视口 */
StartUI->AddToViewport();
}
/** 注册页返回按钮回调事件 */
void AEmptyGameMode::RegisterBackBtnClickedEvent()
{
/** 移除登录页UI */
RegisterUI->RemoveFromViewport();
/** 添加起始页UI到视口 */
StartUI->AddToViewport();
}2、注册页开发
1、蓝图的创建及C++的创建
首先我们看一下注册页面的布局,典型的上下结构,因此我们首先根据素材导入UE4后创建蓝图版的UMG,然后进行设计。需要注意的是要学会使用布局面板和锚点来设计,保证页面在伸缩时保持弹性。接着我们看一下非样式的控件有哪些:左上角的返回按钮
账号输入框
密码输入框
确认密码输入框
注册按钮
加载控件,一个选装的Loading框
Toast控件,显示错误信息的自定义面板,后面会介绍
根据上面的描述,我们为该UMG创建父类。注册页面我们要是使用JSON来向服务器发送数据。同时使用HTTP与服务器进行交互,所以,我们要在Build.cs里面配置JSON和HTTP。
Web服务器已经对非进行了数据校验,但是数据加密并没有实现,这里应该对账号和密码进行MD5加密,这里没有实现,但是企业级项目大家要注意。我们在本地端就简单的实现两次密码是否保持一致的校验即可。如果密码错误,我们就显示Toast面板来提示。注意:这里有个问题,提示信息如果是中文在安卓打包时会报错,现在还没去解决,因此使用的英文。
本地端进行简单的数据校验以后,就进行服务器的请求,首先我们会先对输入的用户名和密码进行拼接,形成JSON数据串,然后再提交到服务器上。具体的代码在cpp文件里可以看到,注释也比较详细。这里提交服务器的时候,比较友好的是先把注册按钮禁用掉,然后显示Loading框,当服务器返回结果后再把Loading框去掉,把注册按钮的禁用去掉。
注册页面头文件:RegisterUserWidget.h/**
* 注册界面UI
*/
UCLASS()
class INFINITYBLADE_API URegisterUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
/** 账号输入框 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UEditableTextBox* AccountBox;
/** 密码输入框 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UEditableTextBox* PasswordBox;
/** 密码确认输入框 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UEditableTextBox* RePasswordBox;
/** 注册按钮 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UButton* RegisterBtn;
/** 后退按钮 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UButton* BackBtn;
/** 加载控件 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UCircularThrobber* LoadingCircle;
/** Toast控件 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UToastUserWidget* ToastWidget;
public:
/** 对象创建后调用的方法 */
virtual bool Initialize() override;
public:
/** 初始化控件引用 */
void Init();
public:
/** 注册按钮点击事件 */
UFUNCTION()
void RegisterBtnClickedEvent();
/** 注册方法 */
void RegisterServer(FString& Nickname,FString& Password);
/** 注册方法的服务器回调 */
void ServerRegisterCompleteCallback(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bIsSuccessful);
};
注册页面cpp文件:RegisterUserWidget.cpp/** 对象创建后调用的方法 */
bool URegisterUserWidget::Initialize()
{
if (!Super::Initialize())
{
return false;
}
/** 初始化控件引用 */
Init();
return true;
}
/** 初始化控件引用 */
void URegisterUserWidget::Init()
{
/** 初始化账号输入框 */
AccountBox = Cast(GetWidgetFromName(TEXT("EditableTextBox_Account")));
/** 初始化密码输入框 */
PasswordBox = Cast(GetWidgetFromName(TEXT("EditableTextBox_Password")));
/** 初始化确认密码输入框 */
RePasswordBox = Cast(GetWidgetFromName(TEXT("EditableTextBox_RePassword")));
/** 初始化注册按钮 */
RegisterBtn = Cast(GetWidgetFromName(TEXT("Button_Register")));
/** 设置注册按钮的点击事件 */
RegisterBtn->OnClicked.AddDynamic(this, &URegisterUserWidget::RegisterBtnClickedEvent);
/** 初始化后退按钮 */
BackBtn = Cast(GetWidgetFromName(TEXT("Button_Back")));
/** 初始化加载控件 */
LoadingCircle = Cast(GetWidgetFromName(TEXT("CircularThrobber")));
/** 初始化Toast控件 */
ToastWidget = Cast(GetWidgetFromName(TEXT("UI_Toast")));
}
/** 注册按钮点击事件 */
void URegisterUserWidget::RegisterBtnClickedEvent()
{
/** 获取注册用户名 */
FString Nickname = AccountBox->GetText().ToString();
/** 获取注册密码 */
FString Password = PasswordBox->GetText().ToString();
/** 获取确认的注册密码 */
FString RePassword = RePasswordBox->GetText().ToString();
/** 判断两次输入的密码是否一致 */
if (!Password.Equals(RePassword))
{
/** 设置提示信息 */
ToastWidget->Msg->SetText(FText::FromString("The Two Input Password Is Not Same!"));
/** 显示Toast */
ToastWidget->SetVisibility(ESlateVisibility::Visible);
return;
}
/** 注册服务器 */
RegisterServer(Nickname, Password);
}
/** 注册方法 */
void URegisterUserWidget::RegisterServer(FString& Nickname, FString& Password)
{
/** 创建要提交的数据 */
FString Data;
/** 创建Json写入器 */
TSharedPtr>> JsonWriter = TJsonWriterFactory>::Create(&Data);
/** 开始写入Json对象 */
JsonWriter->WriteObjectStart();
/** 写入昵称 */
JsonWriter->WriteValue("nickname", Nickname);
/** 写入密码 */
JsonWriter->WriteValue("password", Password);
/** 结束写入Json对象 */
JsonWriter->WriteObjectEnd();
/** 关闭Json写入器 */
JsonWriter->Close();
/** 创建Http请求 */
TSharedPtr Request = FHttpModule::Get().CreateRequest();
/** 设置请求头 */
Request->SetHeader("Content-Type", "application/json;charset=utf-8");
/** 设置请求方式 */
Request->SetVerb("POST");
/** 设置请求的URL */
Request->SetURL("http://www.ujeat.com:7900/user/register-user");
/** 设置上传的数据 */
Request->SetContentAsString(Data);
/** 设置请求成功后的回调事件 */
Request->OnProcessRequestComplete().BindUObject(this, &URegisterUserWidget::ServerRegisterCompleteCallback);
/** 处理请求 */
Request->ProcessRequest();
/** 显示进度控件 */
LoadingCircle->SetVisibility(ESlateVisibility::Visible);
/** 设置注册按钮不可用 */
RegisterBtn->SetIsEnabled(false);
}
/** 注册方法的服务器回调 */
void URegisterUserWidget::ServerRegisterCompleteCallback(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bIsSuccessful)
{
/** 隐藏进度控件 */
LoadingCircle->SetVisibility(ESlateVisibility::Hidden);
/** 设置注册按钮可用 */
RegisterBtn->SetIsEnabled(true);
/** 判断服务器返回状态 */
if (!EHttpResponseCodes::IsOk(Response->GetResponseCode()))
{
/** 如果服务器未返回成功则返回 */
return;
}
/** 创建服务器返回的内容 */
FString Result = Response->GetContentAsString();
/** 创建要解析的JSON对象 */
TSharedPtr JsonObject;
/** 创建Json解析器 */
TSharedRef> JsonReader = TJsonReaderFactory::Create(Result);
/** 解析Json */
bool bIsParseSuccess = FJsonSerializer::Deserialize(JsonReader, JsonObject);
/** 判断是否解析成功 */
if (bIsParseSuccess)
{
/** 获取响应状态 */
FString ResponseStatus = JsonObject->GetStringField("status");
/** 获取响应信息 */
FString ResponseMsg = JsonObject->GetStringField("msg");
/** 设置服务器响应信息 */
ToastWidget->Msg->SetText(FText::FromString(ResponseMsg));
/** 显示Toast */
ToastWidget->SetVisibility(ESlateVisibility::Visible);
}
}2、Toast面板
这里对Toast面板进行简单的介绍,其实和上面开发UMG的思路一致,创建蓝图版再创建C++版,然后C++里持有引用,这里可以看到,引用的控件只是简单的Text控件,我们只对其SetText()即可,这里使用了BackgroundBlur控件进行了背景的模糊处理,这里就不过多赘述了,大家可以自己实现一下。3、登录页开发
登录页面和注册页面类似,这里只把代码复制上,大家可以自行Review,实现思路和注册页面类似,甚至更简单。登录成功以后我们切换关卡到主战场的Level,这里因为后期有排行榜,所以用户登录成功以后的信息需要进行保存,这里我存到了GameInstace里面,顾名思义就是游戏实例,其生命周期是伴随游戏开始到游戏退出的,如果想做持久化的话,这里可以选用其它的方式如SQLite,这里以后再去研究,我们先假定每次打开游戏都需要进行登录。
登录页面头文件:LoginUserWidget.h/**
* 登录界面UI
*/
UCLASS()
class INFINITYBLADE_API ULoginUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
/** 账号输入框 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UEditableTextBox* AccountBox;
/** 密码输入框 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UEditableTextBox* PasswordBox;
/** 登录按钮 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UButton* LoginBtn;
/** 后退按钮 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UButton* BackBtn;
/** 加载控件 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UCircularThrobber* LoadingCircle;
/** Toast控件 */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "UI")
UToastUserWidget* ToastWidget;
public:
/** 创建UserWidget对象后触发 */
virtual bool Initialize() override;
public:
/** 初始化控件引用 */
void Init();
public:
/** 登录按钮点击事件 */
UFUNCTION()
void LoginBtnClickedEvent();
/** 用户登录 */
void LoginServer(FString& Nickname,FString& Password);
/** 服务器响应的回调事件 */
void ServerCompleteCallback(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bIsSuccessful);
};
登录页面cpp文件:LoginUserWidget.cpp#include "LoginUserWidget.h"
/** 创建UserWidget对象后触发 */
bool ULoginUserWidget::Initialize()
{
/** 不加这个判断可能会报错 */
if (!Super::Initialize())
{
return false;
}
/** 初始化对象的引用 */
Init();
return true;
}
/** 初始化控件引用 */
void ULoginUserWidget::Init()
{
/** 初始化账号输入框 */
AccountBox = Cast(GetWidgetFromName(TEXT("EditableTextBox_Account")));
/** 初始化密码输入框 */
PasswordBox = Cast(GetWidgetFromName(TEXT("EditableTextBox_Password")));
/** 初始化登录按钮 */
LoginBtn = Cast(GetWidgetFromName(TEXT("Button_Login")));
/** 设置登录按钮的点击事件 */
LoginBtn->OnClicked.AddDynamic(this, &ULoginUserWidget::LoginBtnClickedEvent);
/** 初始化后退按钮 */
BackBtn = Cast(GetWidgetFromName(TEXT("Button_Back")));
/** 初始化加载控件 */
LoadingCircle = Cast(GetWidgetFromName(TEXT("CircularThrobber")));
/** 初始化Toast控件 */
ToastWidget = Cast(GetWidgetFromName(TEXT("UI_Toast")));
}
/** 登录按钮点击事件 */
void ULoginUserWidget::LoginBtnClickedEvent()
{
/** 获取输入的用户名 */
FString Nickname = AccountBox->GetText().ToString();
/** 获取输入的密码 */
FString Password = PasswordBox->GetText().ToString();
/** 登录服务器 */
LoginServer(Nickname, Password);
}
/** 用户登录 */
void ULoginUserWidget::LoginServer(FString& Nickname, FString& Password)
{
/** 创建要发送的数据 */
FString Data;
/** 创建Json写入器 */
TSharedPtr>> JsonWriter = TJsonWriterFactory>::Create(&Data);
/** 开始写入对象数据 */
JsonWriter->WriteObjectStart();
/** 写入账号昵称 */
JsonWriter->WriteValue("nickname", Nickname);
/** 写入账号密码 */
JsonWriter->WriteValue("password", Password);
/** 结束写入对象数据 */
JsonWriter->WriteObjectEnd();
/** 关闭JsonWriter */
JsonWriter->Close();
/** 创建Http请求对象 */
TSharedPtr HttpRequest = FHttpModule::Get().CreateRequest();
/** 设置请求头 */
HttpRequest->SetHeader("Content-Type", "application/json;charset=utf-8");
/** 设置请求的URL */
HttpRequest->SetURL("http://www.ujeat.com:7900/user/login-user");
/** 设置请求方式为POST */
HttpRequest->SetVerb("POST");
/** 设置上传的JSON数据 */
HttpRequest->SetContentAsString(Data);
/** 设置请求成功后的响应事件 */
HttpRequest->OnProcessRequestComplete().BindUObject(this, &ULoginUserWidget::ServerCompleteCallback);
/** 处理请求 */
HttpRequest->ProcessRequest();
/** 显示进度控件 */
LoadingCircle->SetVisibility(ESlateVisibility::Visible);
/** 设置登录按钮不可用 */
LoginBtn->SetIsEnabled(false);
}
/** 服务器响应的回调事件 */
void ULoginUserWidget::ServerCompleteCallback(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bIsSuccessful)
{
/** 隐藏进度控件 */
LoadingCircle->SetVisibility(ESlateVisibility::Hidden);
/** 设置登录按钮可用 */
LoginBtn->SetIsEnabled(true);
/** 判断服务器返回状态 */
if (!EHttpResponseCodes::IsOk(Response->GetResponseCode()))
{
/** 如果服务器未返回成功则返回 */
return;
}
/** 创建服务器返回的内容 */
FString Result = Response->GetContentAsString();
/** 创建要解析的JSON对象 */
TSharedPtr JsonObject;
/** 创建Json解析器 */
TSharedRef> JsonReader = TJsonReaderFactory::Create(Result);
/** 解析Json */
bool bIsParseSuccess = FJsonSerializer::Deserialize(JsonReader, JsonObject);
/** 判断是否解析成功 */
if (bIsParseSuccess)
{
/** 获取响应状态 */
FString ResponseStatus = JsonObject->GetStringField("status");
/** 获取响应信息 */
FString ResponseMsg = JsonObject->GetStringField("msg");
/** 获取响应的数据对象 */
TSharedPtr Data = JsonObject->GetObjectField("data");
/** 获取用户的id */
FString Id = Data->GetStringField("id");
/** 获取用户的昵称 */
FString Nickname = Data->GetStringField("nickname");
/** 获取用户的密码 */
FString Password = Data->GetStringField("password");
/** 判断是否登录成功 */
if (!Id.IsEmpty())
{
/** 登录成功则保存用户数据到GameInstance */
UCustomGameInstance* GameInstance = Cast(GetWorld()->GetGameInstance());
/** 保存Id */
GameInstance->ContextMap.Add("id", Id);
/** 保存昵称 */
GameInstance->ContextMap.Add("nickname", Nickname);
/** 保存用户密码 */
GameInstance->ContextMap.Add("password", Password);
/** 切换关卡到主战场 */
/** 打开主关卡:注意此处打开关卡的路径 */
UGameplayStatics::OpenLevel(GetWorld(), TEXT("/Game/Maps/Map_War"));
}
else
{
/** 设置服务器响应信息 */
ToastWidget->Msg->SetText(FText::FromString(ResponseMsg));
/** 显示Toast */
ToastWidget->SetVisibility(ESlateVisibility::Visible);
}
}
}
更多推荐
所有评论(0)