UEC++学习(十五)创建、查找、加入会话

 创建会话

基于上篇配置steam在线子系统之后,在Character.h中声明一个会话创建完成时的委托以及回调函数。

#include "Interfaces/OnlineSessionInterface.h"public://指向在线会话界面的指针,将会话接口存储在里面TSharedPtr<class IOnlineSession, ESPMode::ThreadSafe> OnlineSessionInterface;protected://创建游戏会话UFUNCTION(BlueprintCallable)void CreateGameSession();//回调函数,用于处理会话创建完成时的逻辑void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);private://声明会话创建完成时的委托FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;

在Character.cpp的构造函数中绑定委托

	//绑定会话创建完成委托CreateSessionCompleteDelegate.BindUObject(this, &ThisClass::OnCreateSessionComplete);

添加创建会话逻辑,将结果打印到屏幕

OnlineSessionInterface->GetNamedSession(NAME_GameSession):获取会话

OnlineSessionInterface->DestroySession(NAME_GameSession):销毁会话

OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate):添加会话到列表

TSharedPtr<FOnlineSessionSettings> SessionSettings 游戏会话设置

GetWorld()->GetFirstLocalPlayerFromController():获取本地玩家

OnlineSessionInterface->CreateSession:创建会话,参数:网络id,会话名,会话设置

World->ServerTravel():进行服务器旅行

#include "OnlineSessionSettings.h"void AMenuSystemCharacter::CreateGameSession()
{if (!OnlineSessionInterface.IsValid()){return;}//通过NAME_GameSession创建一个临时会话FNamedOnlineSession* ExistingSession = OnlineSessionInterface->GetNamedSession(NAME_GameSession);if (ExistingSession != nullptr){//销毁之前的会话OnlineSessionInterface->DestroySession(NAME_GameSession);}//将委托添加到句柄中OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate);//修改游戏会话设置TSharedPtr<FOnlineSessionSettings> SessionSettings = MakeShareable(new FOnlineSessionSettings());SessionSettings->bIsLANMatch = false;SessionSettings->NumPublicConnections = 4;SessionSettings->bAllowJoinInProgress = true;SessionSettings->bAllowJoinViaPresence = true;SessionSettings->bShouldAdvertise = true;SessionSettings->bUsesPresence = true;//获取本地玩家const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();//将本地玩家的id作为会话房主OnlineSessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *SessionSettings);}void AMenuSystemCharacter::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{if (bWasSuccessful){if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Blue,FString::Printf(TEXT("Created Session: %s"), *SessionName.ToString()));}//打开一个空白地图作为服务器大厅UWorld* World = GetWorld();if (World){World->ServerTravel(FString("/Game/ThirdPerson/Maps/Lobby?listen"));}}else{if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Red,FString(TEXT("Fail to create session")));}}
}

查找会话

在Character.h中添加查找结束委托以及回调函数

	//加入游戏会话UFUNCTION(BlueprintCallable)void JoinGameSession();void OnFindSessionsComplete(bool bWasSuccessful);//声明查找会话完成时的委托FOnFindSessionsCompleteDelegate FindSessionCompleteDelegate;//会话搜索结果TSharedPtr<FOnlineSessionSearch> SessionSearch;

在Character.cpp中,构造函数中绑定委托

	FindSessionCompleteDelegate.BindUObject(this, &ThisClass::OnFindSessionsComplete);

OnlineSessionInterface->FindSessions:查找会话

void AMenuSystemCharacter::JoinGameSession()
{if (!OnlineSessionInterface.IsValid()){return;}OnlineSessionInterface->AddOnFindSessionsCompleteDelegate_Handle(FindSessionCompleteDelegate);SessionSearch = MakeShareable(new FOnlineSessionSearch());SessionSearch->MaxSearchResults = 10000;SessionSearch->bIsLanQuery = false;SessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();OnlineSessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), SessionSearch.ToSharedRef());}void AMenuSystemCharacter::OnFindSessionsComplete(bool bWasSuccessful)
{if (!OnlineSessionInterface.IsValid()){return;}for (FOnlineSessionSearchResult Result : SessionSearch->SearchResults){FString Id = Result.GetSessionIdStr();FString User = Result.Session.OwningUserName;if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Cyan,FString::Printf(TEXT("Id: %s ,User: %s"),*Id, *User));}}
}

加入会话

在Character.h中添加 加入会话结束时的委托和回调

	//加入会话结束时的委托FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);

在构造函数中绑定委托

	JoinSessionCompleteDelegate.BindUObject(this, &ThisClass::OnJoinSessionComplete);

在查找会话阶段的OnFindSessionComplete回调函数中,判断找到的会话类型是否和创建的会话类型一样,如果一样的话就加入会话

Result.Session.SessionSettings.Get(FName("MatchType"), MatchType):获取会话类型

OnlineSessionInterface->JoinSession:加入会话

void AMenuSystemCharacter::OnFindSessionsComplete(bool bWasSuccessful)
{if (!OnlineSessionInterface.IsValid()){return;}for (FOnlineSessionSearchResult Result : SessionSearch->SearchResults){FString Id = Result.GetSessionIdStr();FString User = Result.Session.OwningUserName;if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Cyan,FString::Printf(TEXT("Id: %s ,User: %s"),*Id, *User));}//----------判断会话类型FString MatchType;Result.Session.SessionSettings.Get(FName("MatchType"), MatchType);if (MatchType == FString("FreeForAll")){if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Cyan,FString::Printf(TEXT("Joining Match Type: %s"), *MatchType));}//加入会话OnlineSessionInterface->AddOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate);const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();OnlineSessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, Result);}}
}

在加入会话结束的回调函数中

 GetGameInstance()->GetFirstLocalPlayerController():获取本地玩家控制器

PlayerController->ClientTravel:作为客户端旅行

void AMenuSystemCharacter::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{if (!OnlineSessionInterface.IsValid()){return;}FString Address;if (OnlineSessionInterface->GetResolvedConnectString(NAME_GameSession,Address)){if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Yellow,FString::Printf(TEXT("Connect String : %s"), *Address));}APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController();if (PlayerController){PlayerController->ClientTravel(Address, ETravelType::TRAVEL_Absolute);}}
}

结果: 

玩家1通过按“1”将自己的id作为会话房主,创建一个会话,打开一个空白地图作为服务大厅,玩家2通过按“2”找到类型匹配的会话并以客户端旅行加入会话,

 玩家1在蓝图中通过按键“1”进行调试,调用CreateGameSession函数。

 玩家2在蓝图中通过按键“2”进行调试,调用JoinGameSession函数

(1)如果是打包出来给两台电脑测试的话,首先需要保证Steam在后台运行,两个不同的steam账号下载地址最好改成一样的。然后一台电脑按1创建房间,另外一台电脑按2加入房间。

(2)如果只有一台电脑测试的话,要将steam退出后台,然后在编辑器中选择“独立进程游戏”,玩家数量改为2。使用局域网来完成,一个玩家按1创建房间,另外一个玩家按2加入房间

如果一直显示无法创建成功的话,需要将DefaultEngin.ini文件进行修改

完整代码

 character.h

#include "Interfaces/OnlineSessionInterface.h"public://指向在线会话界面的指针,将会话接口存储在里面TSharedPtr<class IOnlineSession, ESPMode::ThreadSafe> OnlineSessionInterface;protected://创建游戏会话UFUNCTION(BlueprintCallable)void CreateGameSession();//加入游戏会话UFUNCTION(BlueprintCallable)void JoinGameSession();//回调函数,用于处理会话创建完成时的逻辑void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);void OnFindSessionsComplete(bool bWasSuccessful);void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);private://声明会话创建完成时的委托FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;//声明查找会话完成时的委托FOnFindSessionsCompleteDelegate FindSessionCompleteDelegate;//加入会话结束时的委托FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;//会话搜索结果TSharedPtr<FOnlineSessionSearch> SessionSearch;

Character.CPP

#include "Kismet/GameplayStatics.h"
#include "OnlineSubsystem.h"
#include "OnlineSessionSettings.h"//构造函数
AMenuSystemCharacter::AMenuSystemCharacter()
{//绑定会话创建完成委托CreateSessionCompleteDelegate.BindUObject(this, &ThisClass::OnCreateSessionComplete);FindSessionCompleteDelegate.BindUObject(this, &ThisClass::OnFindSessionsComplete);JoinSessionCompleteDelegate.BindUObject(this, &ThisClass::OnJoinSessionComplete);
}//创建会话
void AMenuSystemCharacter::CreateGameSession()
{if (!OnlineSessionInterface.IsValid()){return;}//通过NAME_GameSession创建一个临时会话FNamedOnlineSession* ExistingSession = OnlineSessionInterface->GetNamedSession(NAME_GameSession);if (ExistingSession != nullptr){//销毁之前的会话OnlineSessionInterface->DestroySession(NAME_GameSession);}//将委托添加到句柄中OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate);//修改游戏会话设置TSharedPtr<FOnlineSessionSettings> SessionSettings = MakeShareable(new FOnlineSessionSettings());SessionSettings->bIsLANMatch = false;SessionSettings->NumPublicConnections = 4;SessionSettings->bAllowJoinInProgress = true;SessionSettings->bAllowJoinViaPresence = true;SessionSettings->bShouldAdvertise = true;SessionSettings->bUsesPresence = true;SessionSettings->bUseLobbiesIfAvailable = true;//设置一个键值队。当找到会话的时候需要检查一下会话类型是否和创建的会话一样SessionSettings->Set(FName("MatchType"), FString("FreeForAll"), EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);//获取本地玩家const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();//将本地玩家的id作为会话房主OnlineSessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *SessionSettings);}//创建会话完成时的回调函数
void AMenuSystemCharacter::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{if (bWasSuccessful){if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Blue,FString::Printf(TEXT("Created Session: %s"), *SessionName.ToString()));}//打开一个空白地图作为大厅UWorld* World = GetWorld();if (World){World->ServerTravel(FString("/Game/ThirdPerson/Maps/Lobby?listen"));}}else{if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Red,FString(TEXT("Fail to create session")));}}
}//查找会话
void AMenuSystemCharacter::JoinGameSession()
{if (!OnlineSessionInterface.IsValid()){return;}OnlineSessionInterface->AddOnFindSessionsCompleteDelegate_Handle(FindSessionCompleteDelegate);SessionSearch = MakeShareable(new FOnlineSessionSearch());SessionSearch->MaxSearchResults = 10000;SessionSearch->bIsLanQuery = false;SessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();OnlineSessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), SessionSearch.ToSharedRef());}//查找会话完成时的回调函数
void AMenuSystemCharacter::OnFindSessionsComplete(bool bWasSuccessful)
{if (!OnlineSessionInterface.IsValid()){return;}for (FOnlineSessionSearchResult Result : SessionSearch->SearchResults){FString Id = Result.GetSessionIdStr();FString User = Result.Session.OwningUserName;if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Cyan,FString::Printf(TEXT("Id: %s ,User: %s"), *Id, *User));}//----------判断会话类型FString MatchType;Result.Session.SessionSettings.Get(FName("MatchType"), MatchType);if (MatchType == FString("FreeForAll")){if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Cyan,FString::Printf(TEXT("Joining Match Type: %s"), *MatchType));}//加入会话,OnlineSessionInterface->AddOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate);const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();OnlineSessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, Result);}}
}//加入会话完成时的回调函数
void AMenuSystemCharacter::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{if (!OnlineSessionInterface.IsValid()){return;}FString Address;if (OnlineSessionInterface->GetResolvedConnectString(NAME_GameSession,Address)){if (GEngine){GEngine->AddOnScreenDebugMessage(-1,15.f,FColor::Yellow,FString::Printf(TEXT("Connect String : %s"), *Address));}APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController();if (PlayerController){PlayerController->ClientTravel(Address, ETravelType::TRAVEL_Absolute);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/702899.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

锚点组件--支持点击、滚动高亮锚点

实现一个锚点组件&#xff0c;页面滚动时高亮当前位置锚点、点击锚点时跳转到指定冒点位置&#xff0c;同时选中锚点也高亮 效果图 父组件 import ./index.less; import Anchor from ./Anchor; import Content from ./Content;export default function index() {return (<…

5分钟科普:App开发与广告联盟变现法则

在移动互联网的时代&#xff0c;应用程序&#xff08;App&#xff09;已经成为人们生活的一部分。对于开发者来说&#xff0c;如何通过自己的应用获取收益&#xff0c;是他们需要解决的重要问题。广告联盟作为一种常见的广告变现方式&#xff0c;为开发者提供了一种可能。 广告…

Google I/O 2024:有关AI的一切已公布|TodayAI

2024年谷歌I/O大会圆满落幕&#xff0c;谷歌在会上发布了一系列更新&#xff0c;涵盖从最新的人工智能技术到Android系统的多项改进。此次大会特别关注于谷歌的Gemini人工智能模型&#xff0c;并详细介绍了这些模型如何被融入到Workspace、Chrome等多个应用程序中&#xff0c;展…

炫富神器,简单无脑粘贴复制,闷声发财,当天见收益,无上限封顶

项目主打简单、暴力、易操作、可复制&#xff0c;单人可做、不靠关系走门路、不重投资、可复制放大&#xff01; 今天给大家带来的这个项目&#xff0c;有点暴力&#xff0c;请先做好心理准备&#xff01;谨慎观看&#xff01;&#xff01; 这个项目原理是利用软件生成炫富视频…

ADCIRC+Python深度融合:台风风暴潮模拟、温带风暴潮模拟、天文潮模拟、风暴潮漫滩模拟;ADCIRC模式前处理和后处理等

目录 专题一 ADCIRC背景与原理 专题二 ADCIRC的编译安装 专题三 ADCIRC模式前处理 专题四 ADCIRC案例分析 专题五 Python基础与科学计算 专题六 ADCIRC模式后处理 更多应用 ADCIRC是新一代海洋水动力计算模型&#xff0c;它采用了非结构三角形网格广义波动连续方程的设计…

Go系列:git status 高级技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

智游剪辑1.5.0发布!

智游剪辑1.5.0发布了&#xff0c;快来看看更新了啥功能吧&#xff01; 主页卡片升级 现在功能卡片新增图标&#xff0c;比以前更好看更直观 我的收藏 遇到自己喜欢的功能直接点击收藏就可以了&#xff0c;后面我们就能快速找到这个功能 批量ncm转mp3功能 目前看后台有很多人…

H2-FDetector模型解析

文章目录 1. H2FDetector_layer 类2. RelationAware 类3. MultiRelationH2FDetectorLayer 类4. H2FDetector 类 这个实现包括三个主要部分&#xff1a;H2FDetector_layer、MultiRelationH2FDetectorLayer 和 H2FDetector。每个部分都有其独特的功能和职责。下面是这些组件的详细…

2024年将改变人类生活的七大技术

有没有想过未来会是什么样子&#xff1f;那么&#xff0c;不必等太久&#xff0c;因为2024年将会是充满惊人创新的一年&#xff0c;让你大开眼界。以下是七大新兴的科技创新趋势&#xff0c;它们无疑将在2024年改变我们的生活。 1. 人工智能技术 从智能手机、智能扬声器等日…

Flutter+Getx仿小米商城项目实战教程又新增了Flutter调用原生地图

FlutterGetx仿小米商城项目实战教程基于Flutter3.x录制&#xff0c;课程紧贴企业需求&#xff0c;目前已完结176讲。教程所讲内容支持Android、Ios、华为鸿蒙OS&#xff0c;教程更新于2024年4月09日新增 Flutter 调用百度地图、新增Flutter充电桩项目地图实战。支持2024年3月29…

Arduino-ILI9341驱动开发TFT屏显示任意内容三

Arduino-ILI9341驱动开发TFT屏显示任意内容三 1.概述 这篇文章介绍使用ILI9341驱动提供的函数控制TFT屏显示字符串、图形、符号等等内容的编辑和展示。 2.硬件 2.1.硬件列表 名称数量Arduino Uno12.8" TFT彩色液晶触摸屏模块&#xff08;ILI9431&#xff09;110K 电阻…

TensorFlow的学习

0.基础概念 术语表&#xff1a; https://developers.google.cn/machine-learning/glossary?hlzh-cn#logits 1.快速入门 https://tensorflow.google.cn/tutorials/quickstart/beginner?hlzh-cn 2.基于Keras进行图像分类 https://tensorflow.google.cn/tutorials/keras/cl…