• UE4 Http协议实现Web登陆与注册


    B站教学链接:https://space.bilibili.com/449549424?spm_id_from=333.1007.0.0


    一、Http协议

      Http协议网上有很多介绍,这里不过多介绍。需要可以参考

      https://blog.csdn.net/lingxu6/article/details/124738027

    二、前期准备

    创建UE4 C++项目,在Build.cs中加入模块,UE4需要这些模块才能编译和加载Http和Json格式的数据

    1. using UnrealBuildTool;
    2. public class HttpProject : ModuleRules
    3. {
    4. public HttpProject(ReadOnlyTargetRules Target) : base(Target)
    5. {
    6. PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
    7. PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay","Http","Json", "JsonUtilities","UMG" });
    8. }
    9. }

    三、案例介绍

    UE4封装了HttpModule,Json文件的序列化和反序列化,本案例就是使用了这些模块来进行web服务端的通信

    服务器返回的数据是Json格式的数据

    效果如下:

    第一步:创建C++,三个UserWidget,名为StartWidget,RegisterWidget,LoginWidget,

     第二步,创建一个GameMode ,名为StartGameMode

    第三步 ,创建UMG,名为BP_MyStart,BP_Register,BP_Login

    继承自C++的StartWidget,RegisterWidget,LoginWidget

     

    第四步:代码写入StartWidget

    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #pragma once
    3. #include "CoreMinimal.h"
    4. #include "MyUserWidget.h"
    5. #include "Components/Button.h"
    6. #include "StartWidget.generated.h"
    7. /**
    8. *
    9. */
    10. UCLASS()
    11. class HTTPPROJECT_API UStartWidget : public UMyUserWidget
    12. {
    13. GENERATED_BODY()
    14. public:
    15. UPROPERTY()
    16. UButton* StartButton;
    17. UPROPERTY()
    18. UButton* RegisterButton;
    19. UPROPERTY()
    20. UButton* QuitButton;
    21. public:
    22. virtual bool Initialize() override;
    23. };

    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #include "StartWidget.h"
    3. bool UStartWidget::Initialize()
    4. {
    5. if (!Super::Initialize())
    6. {
    7. return false;
    8. }
    9. //初始化开始按钮
    10. StartButton = Cast<UButton>(GetWidgetFromName(TEXT("Button_Start")));
    11. //初始化注册按钮
    12. RegisterButton = Cast<UButton>(GetWidgetFromName(TEXT("Button_Register")));
    13. //初始化退出按钮
    14. QuitButton = Cast<UButton>(GetWidgetFromName(TEXT("Button_Quit")));
    15. return true;
    16. }

     RegisterWidget代码

    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #pragma once
    3. #include "CoreMinimal.h"
    4. #include "MyUserWidget.h"
    5. #include "Components/Button.h"
    6. #include "Components/EditableTextBox.h"
    7. #include "Components/TextBlock.h"
    8. #include "HTTP/Public/Interfaces/IHttpRequest.h"
    9. #include "HTTP/Public/Interfaces/IHttpResponse.h"
    10. #include "HTTP/Public/Interfaces/IHttpBase.h"
    11. #include "HTTP/Public/HttpModule.h"
    12. #include "Json/Public/Serialization/JsonWriter.h"
    13. #include "Json/Public/Serialization/JsonReader.h"
    14. #include "Json/Public/Serialization/JsonSerializer.h"
    15. #include "Json/Public/Policies/CondensedJsonPrintPolicy.h"
    16. #include "Json/Public/Dom/JsonObject.h"
    17. #include "RegisterWidget.generated.h"
    18. /**
    19. *
    20. */
    21. DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnRegisterResultDelegate, bool, result, FString, message);
    22. UCLASS()
    23. class HTTPPROJECT_API URegisterWidget : public UMyUserWidget
    24. {
    25. GENERATED_BODY()
    26. public:
    27. UPROPERTY()
    28. UButton* RegisterBtn;
    29. UPROPERTY()
    30. UButton* BackBtn;
    31. UPROPERTY()
    32. UEditableTextBox* NicknameInput;
    33. UPROPERTY()
    34. UEditableTextBox* PasswordInput;
    35. UPROPERTY()
    36. UEditableTextBox* RePasswordInput;
    37. UPROPERTY(BlueprintAssignable, Category = "Register")
    38. FOnRegisterResultDelegate OnRegisterResultDelegate;
    39. public:
    40. virtual bool Initialize() override;
    41. UFUNCTION()
    42. void RegisterButtonOnClickEvent();
    43. //注册函数
    44. void AccountRegisterFromServer(FString nickname,FString password);
    45. private:
    46. //绑定回调函数
    47. void RequestComplete(FHttpRequestPtr RequestPtr, FHttpResponsePtr ResponsePtr, bool bIsSuccess);
    48. };

    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #include "RegisterWidget.h"
    3. bool URegisterWidget::Initialize()
    4. {
    5. if (!Super::Initialize())
    6. {
    7. return false;
    8. }
    9. //初始化返回按钮
    10. BackBtn = Cast<UButton>(GetWidgetFromName(TEXT("Button_Return")));
    11. //初始化注册按钮
    12. RegisterBtn = Cast<UButton>(GetWidgetFromName(TEXT("Button_Register")));
    13. //初始化账号输入框
    14. NicknameInput = Cast<UEditableTextBox>(GetWidgetFromName(TEXT("EditableText_Nickname")));
    15. //初始化密码输入框
    16. PasswordInput = Cast<UEditableTextBox>(GetWidgetFromName(TEXT("EditableText_Password")));
    17. //初始化重复密码输入框
    18. RePasswordInput = Cast<UEditableTextBox>(GetWidgetFromName(TEXT("EditableText_RePassword")));
    19. //初始化绑定注册函数
    20. RegisterBtn->OnClicked.AddDynamic(this, &URegisterWidget::RegisterButtonOnClickEvent);
    21. return true;
    22. }
    23. void URegisterWidget::RegisterButtonOnClickEvent()
    24. {
    25. FString Account = NicknameInput->GetText().ToString();
    26. FString PassWord1 = PasswordInput->GetText().ToString();
    27. FString RePassWord1 = RePasswordInput->GetText().ToString();
    28. if (Account.Len()< 2 || Account.Len() > 6)
    29. {
    30. GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("NickName is too long"));
    31. return;
    32. }
    33. if (!PassWord1.Equals(RePassWord1))
    34. {
    35. GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Second password is error"));
    36. }
    37. AccountRegisterFromServer(Account,PassWord1);
    38. RegisterBtn->SetIsEnabled(false);
    39. }
    40. void URegisterWidget::AccountRegisterFromServer(FString nickname, FString password)
    41. {
    42. FString Serverdata;
    43. TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter = TJsonWriterFactory>::Create(&Serverdata);
    44. JsonWriter->WriteObjectStart();
    45. //写入账号
    46. JsonWriter->WriteValue("nickname", nickname);
    47. //写入密码
    48. JsonWriter->WriteValue("password", password);
    49. //关闭写入
    50. JsonWriter->WriteObjectEnd();
    51. //关闭json写入器
    52. JsonWriter->Close();
    53. //创建Http 请求
    54. TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = FHttpModule::Get().CreateRequest();
    55. //设置Header
    56. HttpRequest->SetHeader("Content-Type", "application/json;charset=UTF-8");
    57. HttpRequest->SetVerb("POST");
    58. //设置请求地址
    59. HttpRequest->SetURL("https://........................................");
    60. //设置请求发送的数据
    61. HttpRequest->SetContentAsString(Serverdata);
    62. //绑定回调
    63. HttpRequest->OnProcessRequestComplete().BindUObject(this, &URegisterWidget::RequestComplete);
    64. //发送请求
    65. HttpRequest->ProcessRequest();
    66. }
    67. void URegisterWidget::RequestComplete(FHttpRequestPtr RequestPtr, FHttpResponsePtr ResponsePtr, bool bIsSuccess)
    68. {
    69. UE_LOG(LogTemp, Warning, TEXT(">>request complete"));
    70. UE_LOG(LogTemp, Warning, TEXT("%s"), *(ResponsePtr->GetContentAsString()));
    71. if (!EHttpResponseCodes::IsOk(ResponsePtr->GetResponseCode()))
    72. {
    73. OnRegisterResultDelegate.Broadcast(false, TEXT("Invalid Network"));
    74. UE_LOG(LogTemp, Warning, TEXT("Invalid Network"));
    75. return;
    76. }
    77. //创建一个Json解析器
    78. TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory::Create(ResponsePtr->GetContentAsString());
    79. //创建一个Json对象
    80. TSharedPtr<FJsonObject> JsonObject;
    81. //Json反序列化
    82. bool bIsOk = FJsonSerializer::Deserialize(JsonReader, JsonObject);
    83. //判断解析是否成功
    84. if (bIsOk)
    85. {
    86. int code = JsonObject->GetIntegerField("code");
    87. FString msg = JsonObject->GetStringField("msg");
    88. GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Msg is : %s"),*msg));
    89. if (code != 0)
    90. {
    91. OnRegisterResultDelegate.Broadcast(false, *msg);
    92. return;
    93. }
    94. TSharedPtr<FJsonObject> DataObject = JsonObject->GetObjectField("data");
    95. OnRegisterResultDelegate.Broadcast(true, TEXT("Success"));
    96. UE_LOG(LogTemp, Warning, TEXT("Success"));
    97. }
    98. }

    LoginWidget代码

    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #pragma once
    3. #include "CoreMinimal.h"
    4. #include "GameFramework/Actor.h"
    5. #include "LoginActor.generated.h"
    6. UCLASS()
    7. class HTTPPROJECT_API ALoginActor : public AActor
    8. {
    9. GENERATED_BODY()
    10. public:
    11. // Sets default values for this actor's properties
    12. ALoginActor();
    13. protected:
    14. // Called when the game starts or when spawned
    15. virtual void BeginPlay() override;
    16. public:
    17. // Called every frame
    18. virtual void Tick(float DeltaTime) override;
    19. };
    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #pragma once
    3. #include "CoreMinimal.h"
    4. #include "MyUserWidget.h"
    5. #include "Components/Button.h"
    6. #include "Components/EditableTextBox.h"
    7. #include "Components/TextBlock.h"
    8. #include "HTTP/Public/Interfaces/IHttpRequest.h"
    9. #include "HTTP/Public/Interfaces/IHttpResponse.h"
    10. #include "HTTP/Public/Interfaces/IHttpBase.h"
    11. #include "HTTP/Public/HttpModule.h"
    12. #include "Json/Public/Serialization/JsonWriter.h"
    13. #include "Json/Public/Serialization/JsonReader.h"
    14. #include "Json/Public/Serialization/JsonSerializer.h"
    15. #include "Json/Public/Policies/CondensedJsonPrintPolicy.h"
    16. #include "Json/Public/Dom/JsonObject.h"
    17. #include "LoginWidget.generated.h"
    18. /**
    19. *
    20. */
    21. DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnLoginResultDelegate, bool, result, FString, message);
    22. UCLASS()
    23. class HTTPPROJECT_API ULoginWidget : public UMyUserWidget
    24. {
    25. GENERATED_BODY()
    26. public:
    27. UPROPERTY()
    28. UButton* LoginBtn;
    29. UPROPERTY()
    30. UButton* ReturnBtn;
    31. UPROPERTY()
    32. UEditableTextBox* NicknameInput;
    33. UPROPERTY()
    34. UEditableTextBox* PasswordInput;
    35. public:
    36. virtual bool Initialize() override;
    37. UPROPERTY(BlueprintAssignable, Category = "Register")
    38. FOnLoginResultDelegate OnLoginResultDelegate;
    39. //点击登陆函数
    40. UFUNCTION()
    41. void LoginButtonOnClickEvent();
    42. //登陆方法函数
    43. void AccountLoginFromServer(FString Nickname,FString Password);
    44. private:
    45. //绑定回调函数
    46. void RequestComplete(FHttpRequestPtr RequestPtr, FHttpResponsePtr ResponsePtr, bool bIsSuccess);
    47. };

    StartGameMode的代码

    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #pragma once
    3. #include "CoreMinimal.h"
    4. #include "GameFramework/GameMode.h"
    5. #include "StartWidget.h"
    6. #include "RegisterWidget.h"
    7. #include "LoginWidget.h"
    8. #include "StartGameMode.generated.h"
    9. /**
    10. *
    11. */
    12. UCLASS()
    13. class HTTPPROJECT_API AStartGameMode : public AGameMode
    14. {
    15. GENERATED_BODY()
    16. public:
    17. UPROPERTY()
    18. UStartWidget* MyStartWidget;
    19. UPROPERTY()
    20. URegisterWidget* MyRegisterWidget;
    21. UPROPERTY()
    22. ULoginWidget* MyLoginWidget;
    23. public:
    24. virtual void BeginPlay() override;
    25. UFUNCTION()
    26. void RegisterBtnOnClickEvent();
    27. UFUNCTION()
    28. void RegisterBackBtnOnClickEvent();
    29. UFUNCTION()
    30. void StartBtnOnClickEvent();
    31. UFUNCTION()
    32. void LoginBackBtnOnClickEvent();
    33. };
    1. // Fill out your copyright notice in the Description page of Project Settings.
    2. #include "StartGameMode.h"
    3. void AStartGameMode::BeginPlay()
    4. {
    5. Super::BeginPlay();
    6. MyStartWidget = CreateWidget<UStartWidget>(GetWorld(),LoadClass<UStartWidget>(nullptr,TEXT("WidgetBlueprint'/Game/BP_Start.BP_Start_C'")));
    7. if (MyStartWidget)
    8. {
    9. MyStartWidget->AddToViewport();
    10. MyStartWidget->RegisterButton->OnClicked.AddDynamic(this, &AStartGameMode::RegisterBtnOnClickEvent);
    11. MyStartWidget->StartButton->OnClicked.AddDynamic(this,&AStartGameMode::StartBtnOnClickEvent);
    12. }
    13. MyRegisterWidget = CreateWidget<URegisterWidget>(GetWorld(), LoadClass<URegisterWidget>(nullptr, TEXT("WidgetBlueprint'/Game/BP_Register.BP_Register_C'")));
    14. if (MyRegisterWidget)
    15. {
    16. MyRegisterWidget->BackBtn->OnClicked.AddDynamic(this, &AStartGameMode::RegisterBackBtnOnClickEvent);
    17. }
    18. MyLoginWidget = CreateWidget<ULoginWidget>(GetWorld(), LoadClass<ULoginWidget>(nullptr,TEXT("WidgetBlueprint'/Game/BP_Login.BP_Login_C'")));
    19. if (MyLoginWidget)
    20. {
    21. MyLoginWidget->ReturnBtn->OnClicked.AddDynamic(this, &AStartGameMode::LoginBackBtnOnClickEvent);
    22. }
    23. }
    24. void AStartGameMode::RegisterBtnOnClickEvent()
    25. {
    26. MyStartWidget->RemoveFromParent();
    27. MyRegisterWidget->AddToViewport();
    28. }
    29. void AStartGameMode::RegisterBackBtnOnClickEvent()
    30. {
    31. MyRegisterWidget->RemoveFromParent();
    32. MyStartWidget->AddToViewport();
    33. GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("RegisterBack"));
    34. }
    35. void AStartGameMode::StartBtnOnClickEvent()
    36. {
    37. MyStartWidget->RemoveFromParent();
    38. MyLoginWidget->AddToViewport();
    39. }
    40. void AStartGameMode::LoginBackBtnOnClickEvent()
    41. {
    42. MyLoginWidget->RemoveFromParent();
    43. MyStartWidget->AddToViewport();
    44. GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("LoginBack"));
    45. }

    第五步:世界设置中选中StartGameMode

    第六步:测试运行

     到此即可

  • 相关阅读:
    AIGC ChatGPT4总结SQL优化细节操作
    Vue源码学习(四):<templete>渲染第三步,将ast语法树转换为渲染函数
    大数据讲课笔记1.1 安装配置CentOS
    vue后台实现点击图片放大
    MyBatis框架
    电力系统潮流计算(牛顿-拉夫逊法、高斯-赛德尔法、快速解耦法)【6节点 9节点 14节点 26节点 30节点 57节点】(Matlab代码实现)
    Docker搭建Mylar
    常见的C/C++开源数值计算库
    04 如何进行数据表表分区? | OushuDB 数据库使用入门
    LeetCode题:70爬楼梯,126斐波那契数
  • 原文地址:https://blog.csdn.net/qq_43021038/article/details/126608528