虚幻引擎5 Gameplay框架(五)

虚幻引擎5 Gameplay框架(五)

码农世界 2024-06-16 后端 82 次浏览 0个评论

Gameplay重要类及重要功能使用方法(四)

DeveloperSetting

  • DeveloperSetting是在虚幻引擎中是一个基类,主要用于创建和管理开发者设置相关的类。这类设置允许开发者自定义或调整项目中的各种配置选项,而无需直接修改代码或构建设置。这些设置可以是关于渲染、物理、输入、网络等多方面的,为游戏或应用的开发过程提供了高度的灵活性和可配置性。继承自UObject类

  • 创建一个DeveloperSetting类,这种一般在企业级开发用的比较多,用于拓展

  • 写一个功能,用来理解,使用这个拓展类,让游戏设置选择是否保存游戏血量数据并写入到配置文件中

    虚幻引擎5 Gameplay框架(五)

  • 控制是否保存游戏数据的逻辑,默认为真

    虚幻引擎5 Gameplay框架(五)

  • 是否需要保存游戏数据逻辑

    虚幻引擎5 Gameplay框架(五)

  • 是否读取存档数据逻辑

    虚幻引擎5 Gameplay框架(五)

  • 运行结果,此时项目设置里面会出现一个GPPSetting的设置,默认保存游戏为真,此时就会默认保存游戏,读取游戏存档,如果去掉勾就不会默认保存与读取了

    虚幻引擎5 Gameplay框架(五)

    虚幻引擎5 Gameplay框架(五)

  • 通过引擎对配置文件做出实时改变只需要添加一个宏标记类说明符defaultconfig,能实时在配置文件ini中做出改变

    虚幻引擎5 Gameplay框架(五)

  • 运行结果

    虚幻引擎5 Gameplay框架(五)

    虚幻引擎5 Gameplay框架(五)

    GameSession简介与重要方法的执行流程

    GameSession简单介绍

    • 开发一个多人游戏中,客户端需要一个Session机制链接到服务器,在这个过程中以便服务器验证客户端的合法条件
    • GameSession可以看做是GamePlay框架与OnlineSession的接口
    • 使用GameSession过程当中主要依赖的方法就是虚幻引擎提供的接口,虚幻引擎中提供不同网络平台的接口

      虚幻引擎5 Gameplay框架(五)

      重要方法的执行流程

      • 创建一个GameSession类,查看其中重要方法的执行顺序

        虚幻引擎5 Gameplay框架(五)

      • 重写这几个方法查看执行顺序

        虚幻引擎5 Gameplay框架(五)

        虚幻引擎5 Gameplay框架(五)

      • 注册GameSession到GameMode里面

        虚幻引擎5 Gameplay框架(五)

      • 使用服务器批处理脚本查看结果可以发现:RegisterServer早于BeginPlay也早于GameMode中的BenginPlay,然后这里面没有执行RegisterPlayer只注册了自己的服务器到游戏会话当中

        虚幻引擎5 Gameplay框架(五)

      • 然后在使用客户端批处理脚本查看结果:先执行RegisterPlayer了,服务器那边只执行注册服务器的,客户端这边执行注册角色的

        虚幻引擎5 Gameplay框架(五)

      • 实验结果说明:网络链接游戏会话创建就得创建两个,一个给客户端创建一个游戏会话,一个给服务器创建一个游戏会话,把它们共同注册到会话当中,这样客户端才能找到服务器,服务器也可以接受客户端链接。游戏会话就相当于是中间枢纽

        为游戏大厅创建的框架类

        • 新建一个空白关卡做为游戏大厅

          虚幻引擎5 Gameplay框架(五)

        • 然后创建会话大厅的GameMode、Character、GameSession、HUD、PlayerController类,注册到GameMode里面

          虚幻引擎5 Gameplay框架(五)

          虚幻引擎5 Gameplay框架(五)

          创建会话逻辑

          • 首先使用OnlineSubsystem是作为插件使用的,所以得在编译模块加入两个模块

            虚幻引擎5 Gameplay框架(五)

          • 在服务器GameSession类中添加两个函数与一个委托

            虚幻引擎5 Gameplay框架(五)

          • 编写逻辑
            bool AGPPGameSession::CreateSession()
            {
            	IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld());
            	if (OnlineSub)
            	{
            		//拿接口
            		IOnlineSessionPtr SessionPtr = OnlineSub->GetSessionInterface();
            		if (SessionPtr.IsValid())
            		{
            			//进行一些必要设置
            			FOnlineSessionSettings Settings;
            			Settings.NumPublicConnections = 0;
            			Settings.bShouldAdvertise = true;
            			Settings.bAllowJoinInProgress = true;
            			Settings.bIsDedicated = true;
            			Settings.bIsLANMatch = true;
            			Settings.bUsesPresence = false;
            			Settings.bAllowInvites = true;
            			Settings.bAllowJoinViaPresence = true;
            			//设置游戏模式
            			Settings.Set(SETTING_GAMEMODE, FString("StandMatch"), EOnlineDataAdvertisementType::ViaOnlineService);
            			//设置游戏地图
            			Settings.Set(SETTING_MAPNAME, GetWorld()->GetMapName(), EOnlineDataAdvertisementType::ViaOnlineService);
            			
            			//绑定委托句柄,回调函数
            			OnCreateSessionCompleteDelegateHandle = SessionPtr->AddOnCreateSessionCompleteDelegate_Handle(
            				FOnCreateSessionCompleteDelegate::CreateUObject(this, &AGPPGameSession::OnCreateSessionComplete));
            			
            			//创建GameSession
            			bool Result = SessionPtr->CreateSession(0, FName("NAME_GameSession2"), Settings);
            			return Result;
            		}
            	}
            	return false;
            }
            void AGPPGameSession::OnCreateSessionComplete(FName IsSessionName, bool bWasSuccessful)
            {
            	IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld());
            	if (OnlineSub)
            	{
            		//拿接口
            		IOnlineSessionPtr SessionPtr = OnlineSub->GetSessionInterface();
            		if (SessionPtr)
            		{
            			//拿到GameSession状态
            			EOnlineSessionState::Type GameSessionState = SessionPtr->GetSessionState(IsSessionName);
            			//清空句柄
            			SessionPtr->ClearOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegateHandle);
            		}
            	}
            }
            
            • 这段代码解释

              虚幻引擎5 Gameplay框架(五)

            • FOnlineSessionSettings源码

              虚幻引擎5 Gameplay框架(五)

            • 添加头文件

              虚幻引擎5 Gameplay框架(五)

              #include "Online.h"
              #include "OnlineSubsystem.h"
              #include "OnlineSubsystemUtils.h"
              #include "OnlineSessionSettings.h"
              #include "Online/OnlineSessionNames.h"
              #include "OnlineSubsystemTypes.h"
              #include "Interfaces/OnlineSessionDelegates.h"
              
              • 写完逻辑后,如果报错编译器反应不过来,可以到项目中重新编译建立项目

                虚幻引擎5 Gameplay框架(五)

              • 最后在RegisterServer函数中注册服务器
                void AGPPGameSession::RegisterServer()
                {
                	Super::RegisterServer();
                	UE_LOG(MyLog_GPPGameSession, Log, TEXT("----RegisterServer---- NetMode:%s"), *UBFL_LogManager::GetNetModeStr(this));
                	//创建服务器
                	CreateSession();
                }
                

                客户端_FindSession和JoinSession逻辑

                • 实现查找服务器与加入服务器,将之前直接在控制器中直接加入的服务器的代码逻辑注释掉

                  虚幻引擎5 Gameplay框架(五)

                  HallPlayerController类中

                  • 我们在HallPlayerController函数中创建三个函数,一个用来加入房间,查找房间与测试函数

                    虚幻引擎5 Gameplay框架(五)

                  • HallPlayerController::JoinSession的函数逻辑,GameSession->JoinSession(ID, SessionIndexInSerarchResults)这个函数逻辑还没有实现,放到后面去实现。先不管

                    虚幻引擎5 Gameplay框架(五)

                  • AHallPlayerController::FindSession的函数逻辑,GameSeesion->FindSession()这个函数逻辑还没有实现,放到后面去实现。先不管

                    虚幻引擎5 Gameplay框架(五)

                  • 测试函数,运行结果会自动进入第一个房间

                    虚幻引擎5 Gameplay框架(五)

                    HallPlayerController.h
                    // Fill out your copyright notice in the Description page of Project Settings.
                    #pragma once
                    #include "CoreMinimal.h"
                    #include "GameFramework/PlayerController.h"
                    #include "HallPlayerController.generated.h"
                    /**
                     * 
                     */
                    UCLASS()
                    class GAMEPLAYCODEPARSING_API AHallPlayerController : public APlayerController
                    {
                    	GENERATED_BODY()
                    public:
                    	//加入房间
                    	UFUNCTION(BlueprintCallable, Category = "PlayerNetSeesion")
                    	bool JoinSession(int32 SessionIndexInSerarchResults);
                    	//查找房间
                    	UFUNCTION(BlueprintCallable,Category = "PlayerNetSession")
                    	void FindSession();
                    	//测试函数
                    	UFUNCTION(BlueprintCallable,Category="PlayerNetSession")
                    	void FindSessionComplete();
                    };
                    
                    HallPlayerController.cpp
                    // Fill out your copyright notice in the Description page of Project Settings.
                    #include "HallPlayerController.h"
                    #include "HallGameSession.h"
                    #include "GameFramework/GameModeBase.h"
                    bool AHallPlayerController::JoinSession(int32 SessionIndexInSerarchResults)
                    {
                    	if (GetNetMode() == NM_Standalone)//是否是单机状态
                    	{
                    		if (UWorld* const World = GetWorld())//拿取当前世界
                    		{
                    			if (AGameModeBase* const GM = World->GetAuthGameMode())//拿取当前世界的GameMode
                    			{
                    				if (AHallGameSession* GameSession = Cast(GM->GameSession))//有了GameMode就可以拿到Session了
                    				{
                    					if (ULocalPlayer* LocalPlayer = GetLocalPlayer())//有了Session就可以拿到本地的玩家了
                    					{
                    						//通过本地玩家拿取玩家在网络中的ID
                    						const TSharedPtr ID = LocalPlayer->GetPreferredUniqueNetId().GetUniqueNetId();
                    						//ID与要加入的房间号传入到我们在GameSession中自定义函数中
                    						bool Result = GameSession->JoinSession(ID, SessionIndexInSerarchResults);
                    						return Result;
                    					}
                    				}
                    			}
                    		}
                    	}
                    	return false;
                    }
                    void AHallPlayerController::FindSession()
                    {
                    	if (GetNetMode() == NM_Standalone)//是否是单机状态
                    	{
                    		if (UWorld* const World = GetWorld())//拿取当前世界
                    		{
                    			if (AGameModeBase* const GM = World->GetAuthGameMode())//拿到Session了
                    			{
                    				if (AHallGameSession* GameSeesion = Cast(GM->GameSession))//拿到本地的玩家了
                    				{
                    					GameSeesion->FindSession();//调用我们在GameSession中的查找自定义房间函数
                    				}
                    			}
                    		}
                    	}
                    }
                    void AHallPlayerController::FindSessionComplete()
                    {
                    	JoinSession(0);
                    }
                    

                    HallGameSession类中

                    • 然后在HallGameSession类中去实现查找房间发现房间的逻辑
                    • 新建几个函数与委托

                      虚幻引擎5 Gameplay框架(五)

                    • AHallGameSession::FindSession函数逻辑

                      虚幻引擎5 Gameplay框架(五)

                    • AHallGameSession::OnFindSessionComplete函数逻辑

                      虚幻引擎5 Gameplay框架(五)

                    • AHallGameSession::JoinSession函数逻辑

                      虚幻引擎5 Gameplay框架(五)

                    • AHallGameSession::OnJoinSessionComplete函数逻辑

                      虚幻引擎5 Gameplay框架(五)

                    • BeginPlay中的逻辑,在BeginPlay中去查找房间,这样就会自动化运行上面的所有逻辑了

                      虚幻引擎5 Gameplay框架(五)

                      HallGameSession.h
                      // Fill out your copyright notice in the Description page of Project Settings.
                      #pragma once
                      #include "CoreMinimal.h"
                      #include "GameFramework/GameSession.h"
                      #include "OnlineSessionSettings.h"
                      #include "Interfaces/OnlineSessionInterface.h"
                      #include "HallGameSession.generated.h"
                      /**
                       * 
                       */
                      UCLASS()
                      class GAMEPLAYCODEPARSING_API AHallGameSession : public AGameSession
                      {
                      	GENERATED_BODY()
                      public:
                      	virtual void BeginPlay() override;
                      	//查找房间
                      	void FindSession();
                      	//加入房间
                      	bool JoinSession(TSharedPtr UserId, int32 SessionIndexInSerarchResults);
                      	//回调函数
                      	void OnJoinSessionComplete(FName InSessionName, EOnJoinSessionCompleteResult::Type Result);
                      	void OnFindSessionComplete(bool bWasSuccessful);
                      private:
                      	//委托
                      	FDelegateHandle OnFindSessionCompleteDelegateHandle;
                      	FDelegateHandle OnJoinSessionCompleteDelegateHandle;
                      	//缓存查找结果
                      	TSharedPtr SearchSetting;
                      };
                      
                      HallGameSession.cpp
                      // Fill out your copyright notice in the Description page of Project Settings.
                      #include "HallGameSession.h"
                      #include "OnlineSubsystem.h"
                      #include "Online.h"
                      #include "OnlineSubsystemUtils.h"
                      #include "OnlineSessionSettings.h"
                      #include "Online/OnlineSessionNames.h"
                      #include "OnlineSubsystemTypes.h"
                      #include "Interfaces/OnlineSessionDelegates.h"
                      #include "../GPProjectGameInstance.h"
                      #include "HallPlayerController.h"
                      #include "../Utils/BFL_LogManager.h"
                      DEFINE_LOG_CATEGORY_STATIC(MyLog_HallGameSession, Log, All)
                      void AHallGameSession::BeginPlay()
                      {
                      	Super::BeginPlay();
                      	if (GetNetMode() == NM_Standalone)
                      	{
                      		FindSession();
                      	}
                      }
                      void AHallGameSession::FindSession()
                      {
                      	IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld());
                      	if (OnlineSub)
                      	{
                      		//拿接口
                      		IOnlineSessionPtr SessionPtr = OnlineSub->GetSessionInterface();
                      		if (SessionPtr.IsValid())
                      		{
                      			SearchSetting = SearchSetting = MakeShareable(new FOnlineSessionSearch());
                      			SearchSetting->TimeoutInSeconds = 30.;//等待搜索结果的时间
                      			SearchSetting->bIsLanQuery = true;//查询用于局域网匹配
                      			//回调  在完成对在线会话的搜索时触发
                      			OnFindSessionCompleteDelegateHandle = SessionPtr->AddOnFindSessionsCompleteDelegate_Handle(
                      				FOnFindSessionsCompleteDelegate::CreateUObject(this, &AHallGameSession::OnFindSessionComplete));
                      			//拿取GameInstance
                      			if (UGPProjectGameInstance* GI = Cast(GetWorld()->GetGameInstance()))
                      			{
                      				if (ULocalPlayer* LocalPlayer = GI->GetFirstGamePlayer())//拿取本地玩家
                      				{
                      					//通过本地玩家拿取在服务器中的ID
                      					const TSharedPtr UserID = LocalPlayer->GetPreferredUniqueNetId().GetUniqueNetId();
                      					TSharedRef SearchSettingRef = SearchSetting.ToSharedRef();
                      					//查找房间
                      					SessionPtr->FindSessions(*UserID, SearchSettingRef);
                      				}
                      			}
                      		}
                      	}
                      }
                      void AHallGameSession::OnFindSessionComplete(bool bWasSuccessful)
                      {
                      	IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld());
                      	if (OnlineSub)
                      	{
                      		//拿接口
                      		IOnlineSessionPtr SessionPtr = OnlineSub->GetSessionInterface();
                      		if (SessionPtr.IsValid())
                      		{
                      			//清空句柄
                      			SessionPtr->ClearOnFindSessionsCompleteDelegate_Handle(OnFindSessionCompleteDelegateHandle);
                      		}
                      	}
                      	if (UGPProjectGameInstance* GI = Cast(GetWorld()->GetGameInstance()))
                      	{
                      		if (AHallPlayerController* PC = Cast(GI->GetFirstLocalPlayerController()))
                      		{
                      			UE_LOG(MyLog_HallGameSession, Log, TEXT("OnFindSessionComplete-------bWasSuccessful:%d"), bWasSuccessful);
                      			//调用测试函数
                      			PC->FindSessionComplete();
                      		}
                      	}
                      }
                      bool AHallGameSession::JoinSession(TSharedPtr UserId, int32 SessionIndexInSerarchResults)
                      {
                      	IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld());
                      	if (OnlineSub)
                      	{	//获取接口
                      		IOnlineSessionPtr SessionPtr = OnlineSub->GetSessionInterface();
                      		if (SessionPtr.IsValid())
                      		{
                      			//回调  在联机会话的加入过程完成时触发的委托
                      			OnJoinSessionCompleteDelegateHandle = SessionPtr->AddOnJoinSessionCompleteDelegate_Handle(
                      				FOnJoinSessionCompleteDelegate::CreateUObject(this, &AHallGameSession::OnJoinSessionComplete));
                      			//发现的房间
                      			int32 FindNum = SearchSetting->SearchResults.Num();
                      			if (SessionIndexInSerarchResults > -1 && SessionIndexInSerarchResults < FindNum)
                      			{
                      				UE_LOG(MyLog_HallGameSession, Log, TEXT("----JoinSession---- SearchResults:%d"), SearchSetting->SearchResults.Num());
                      				//将转房间ID数据换成FOnlineSessionSearchResult&数据
                      				const FOnlineSessionSearchResult& SearchResult = SearchSetting->SearchResults[SessionIndexInSerarchResults];
                      				bool Result = SessionPtr->JoinSession(*UserId, FName("NAME_GameSession2"), SearchResult);//加入房间
                      				return Result;
                      			}
                      		}
                      	}
                      	return false;
                      }
                      void AHallGameSession::OnJoinSessionComplete(FName InSessionName, EOnJoinSessionCompleteResult::Type Result)
                      {
                      	IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld());
                      	if (OnlineSub)
                      	{
                      		//获取接口
                      		IOnlineSessionPtr SessionPtr = OnlineSub->GetSessionInterface();
                      		if (SessionPtr.IsValid())
                      		{
                      			//清空句柄
                      			SessionPtr->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);
                      			if (Result == EOnJoinSessionCompleteResult::Success)
                      			{
                      				if (AHallPlayerController* PC = Cast(GetWorld()->GetFirstPlayerController()))
                      				{
                      					//充当之前在GamePlayPlayerController直连服务器中的FURL map 的作用
                      					FString ConnectString;
                      					//GetResolvedConnectString:返回用于加入匹配的特定于平台的连接信息。从连接完成的委托调用此函数
                      					if (SessionPtr->GetResolvedConnectString(FName("NAME_GameSession2"), ConnectString))
                      					{
                      						FString PlayerName = "Null";
                      						//获取命令行中的角色名字
                      						if (FParse::Value(FCommandLine::Get(), TEXT("PlayerName="), PlayerName)) {}
                      						//旅行到不同的地图或者地址
                      						PC->ClientTravel(ConnectString + "?PN=" + PlayerName, TRAVEL_Absolute);
                      						UE_LOG(MyLog_HallGameSession, Log, TEXT("----OnJoinSessionComplete---- NetMode:%s"), *UBFL_LogManager::GetNetModeStr(this));
                      						UE_LOG(MyLog_HallGameSession, Log, TEXT("----OnJoinSessionComplete---- ConnectString:%s"), *ConnectString);
                      					}
                      				}
                      			}
                      		}
                      	}
                      }
                      

                      运行结果

                      • 将客户端中的批处理脚本进行修改,进入地图改成我们会话大厅的地图

                        虚幻引擎5 Gameplay框架(五)

                      • 最后在去GPPGameSession类中,将我们之前写的这个公共可连接数量改为1,之前写的0。

                        虚幻引擎5 Gameplay框架(五)

                      • 打开服务器与客户端脚本,运行结果

                        虚幻引擎5 Gameplay框架(五)

                        虚幻引擎5 Gameplay框架(五)

                        虚幻引擎5 Gameplay框架(五)

                        客户端本地获取房间信息逻辑

                        • 首先在HallGameSession类中创建一个结构体用来保存查找到的房间结果里面的数据

                          虚幻引擎5 Gameplay框架(五)

                        • 删除HallPlayerController类中的测试函数,改为在蓝图中实现的函数,传入我们需要的房间结果的数据信息

                          虚幻引擎5 Gameplay框架(五)

                        • 在HallGameSession的OnFindSessionComplete函数中提取房间信息

                          虚幻引擎5 Gameplay框架(五)

                        • AHallGameSession::OnFindSessionComplete(bool bWasSuccessful)函数
                          void AHallGameSession::OnFindSessionComplete(bool bWasSuccessful)
                          {
                          	IOnlineSubsystem* OnlineSub = Online::GetSubsystem(GetWorld());
                          	if (OnlineSub)
                          	{
                          		//拿接口
                          		IOnlineSessionPtr SessionPtr = OnlineSub->GetSessionInterface();
                          		if (SessionPtr.IsValid())
                          		{
                          			//清空句柄
                          			SessionPtr->ClearOnFindSessionsCompleteDelegate_Handle(OnFindSessionCompleteDelegateHandle);
                          		}
                          	}
                          	if (UGPProjectGameInstance* GI = Cast(GetWorld()->GetGameInstance()))
                          	{
                          		if (AHallPlayerController* PC = Cast(GI->GetFirstLocalPlayerController()))
                          		{
                          			TArray UISessionList;//用来保存结果信息的自定义结构体数组
                          			TArray ResultList = SearchSetting->SearchResults;//拿取信息
                          			for (int32 SearchIdx = 0; SearchIdx < ResultList.Num(); SearchIdx++)
                          			{
                          				//查找的房间结果数据
                          				const FOnlineSessionSearchResult& SearchResult = ResultList[SearchIdx];
                          				FUISessionInfo UISession;
                          				UISession.SearchResultIndex = SearchIdx;//房间序号
                          				UISession.SessionName = SearchResult.Session.OwningUserName; //会话的名字
                          				//玩家数量 = 公共的链接 + 私有的链接 - 已经公开的链接 - 已经公开的私有链接
                          				UISession.PlayerNum = SearchResult.Session.SessionSettings.NumPublicConnections +
                          					SearchResult.Session.SessionSettings.NumPrivateConnections -
                          					SearchResult.Session.NumOpenPublicConnections - SearchResult.Session.NumOpenPrivateConnections;
                          				//房间最大数量 = 公共的链接 + 私有的链接
                          				UISession.PlayerMaxNum = SearchResult.Session.SessionSettings.NumPublicConnections +
                          					SearchResult.Session.SessionSettings.NumPrivateConnections;
                          				//Ping
                          				UISession.Ping = SearchResult.PingInMs;
                          				//游戏模式
                          				SearchResult.Session.SessionSettings.Get(SETTING_GAMEMODE, UISession.GameType);
                          				//游戏地图
                          				SearchResult.Session.SessionSettings.Get(SETTING_MAPNAME, UISession.MapName);
                          				//赋值到我们的自定义结构体数组中
                          				UISessionList.Emplace(UISession);
                          			}
                          			UE_LOG(MyLog_HallGameSession, Log, TEXT("OnFindSessionComplete-------bWasSuccessful:%d"), bWasSuccessful);
                          			//调用测试函数
                          			PC->FindSessionComplete(UISessionList);
                          		}
                          	}
                          }
                          
                          • 新建HallGameMode与HUD、PlayerController的蓝图类,填入世界设置

                            虚幻引擎5 Gameplay框架(五)

                          • 在HallPlayerController蓝图中去获取房间信息

                            虚幻引擎5 Gameplay框架(五)

                            通过按钮点击进入房间

                            • 创建会话大厅的UI界面

                              虚幻引擎5 Gameplay框架(五)

                              虚幻引擎5 Gameplay框架(五)

                            • 在HallHUD蓝图中创建这个UI

                              虚幻引擎5 Gameplay框架(五)

                            • 在HallPlayerController蓝图中勾选显示鼠标

                              虚幻引擎5 Gameplay框架(五)

                            • 点击进入房间按钮的时候就加入到房间逻辑

                              虚幻引擎5 Gameplay框架(五)

                            • 使用服务器与客户端的批处理脚本,运行结果

                              虚幻引擎5 Gameplay框架(五)

                              虚幻引擎5 Gameplay框架(五)

                              通过按钮点击查找房间

                              • 制作游戏大厅的显示列表的UI

                                虚幻引擎5 Gameplay框架(五)

                              • 创建房间列表的UI蓝图进行制作

                                虚幻引擎5 Gameplay框架(五)

                              • 然后在创建一个函数进行读取这些变量的逻辑进行赋值到UI上

                                虚幻引擎5 Gameplay框架(五)

                              • 添加这个UI蓝图到列表中

                                虚幻引擎5 Gameplay框架(五)

                              • 刷新按钮逻辑

                                虚幻引擎5 Gameplay框架(五)

                              • 使用服务器与客户端的批处理脚本,运行结果

                                虚幻引擎5 Gameplay框架(五)

                                虚幻引擎5 Gameplay框架(五)

                                客户端点击加入选中条目房间

                                • 将列表UI重新调整一下

                                  虚幻引擎5 Gameplay框架(五)

                                • 给背景创建一个事件

                                  虚幻引擎5 Gameplay框架(五)

                                • 创建一个BPUI_HallSession的实例变量,打开可编辑实例与生成时公开

                                  虚幻引擎5 Gameplay框架(五)

                                • 回BPUI_HallSession蓝图中,将创建列表UI控件的节点刷新一下,将自己的引用传入进去

                                  虚幻引擎5 Gameplay框架(五)

                                • 创建一个传入房间的变量和一个更新这个房间变量的函数

                                  虚幻引擎5 Gameplay框架(五)

                                  虚幻引擎5 Gameplay框架(五)

                                • 点击背景事件逻辑

                                  虚幻引擎5 Gameplay框架(五)

                                • 在更新房间变量处也添加一个测试打印,打印房间号

                                  虚幻引擎5 Gameplay框架(五)

                                • 将加入房间的默认0号换成我们的传入的房间号

                                  虚幻引擎5 Gameplay框架(五)

                                • 将列表蓝图中的垂直框也就是信息栏改为非可命中测试(自身和所有子项),这样就点击文字信息栏也选中这个房间

                                  虚幻引擎5 Gameplay框架(五)

                                • 使用服务器与客户端的批处理脚本,运行结果

                                  虚幻引擎5 Gameplay框架(五)

                                  虚幻引擎5 Gameplay框架(五)

                                  选中房间条目UI颜色变化

                                  • 在BP_HallSingleList蓝图的InitData函数中添加两个线性颜色变量,InitData函数每次刷新房间后,就会给房间默认的颜色

                                    虚幻引擎5 Gameplay框架(五)

                                  • 然后创建两个函数,一个是恢复颜色,一个是选择后改变颜色

                                    虚幻引擎5 Gameplay框架(五)

                                    虚幻引擎5 Gameplay框架(五)

                                  • 当我们点击服务器的时候就改变颜色

                                    虚幻引擎5 Gameplay框架(五)

                                  • 在更新更新房间序号函数里面存一下BP_HallSingleList蓝图变量,这样就知道点击了那个房间了

                                    虚幻引擎5 Gameplay框架(五)

                                  • 到BP_HallSingleList蓝图里面的点击背景的事件中,将更新的更新房间号函数的自己传入参数,告诉主UI,现在点击的是自己,保存自己,这样就拿到上一个房间了

                                    虚幻引擎5 Gameplay框架(五)

                                  • 更新房间序号函数添加一个判断逻辑,如果上一个点击的房间对象还有效就改成默认颜色,否则还是原本逻辑执行,第一次运行,这个地方因为没有点击房间,这里必定为空,所以执行原本的逻辑

                                    虚幻引擎5 Gameplay框架(五)

                                  • 启动两个服务器测试运行结果

                                    虚幻引擎5 Gameplay框架(五)

转载请注明来自码农世界,本文标题:《虚幻引擎5 Gameplay框架(五)》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,82人围观)参与讨论

还没有评论,来说两句吧...

Top