UE4/5多人游戏详解(七、自定义委托,实现寻找会话和加入会话的函数,通过Steam进行两台电脑的联机)

这篇具有很好参考价值的文章主要介绍了UE4/5多人游戏详解(七、自定义委托,实现寻找会话和加入会话的函数,通过Steam进行两台电脑的联机)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

可能出现问题(在六部分的测试可能无法连接的问题【在末尾加上了,怕有人没看见在这里写一下】)

自定义委托

调整位置

创建更多的委托和回调函数给菜单:

多播和动态多播

 代码:

委托变量

 代码:

回调函数

 代码:

绑定委托和动态函数:

 代码:

头文件添加

 代码:

实现加入按钮:

实现寻找函数:

 代码:

实现寻找的回调函数

 代码:

菜单类的onfind回调函数

 代码:

加入会话函数:

 代码:

加入会话的回调函数:

 代码:

菜单内的加入回调函数

 代码:

防止可能出现的意外进行的添加:

 代码1:

 代码2:


可能出现问题(在六部分的测试可能无法连接的问题【在末尾加上了,怕有人没看见在这里写一下】)

打包测试发现在连接steam的情况下无法创建会话

对于这种情况,我们打开:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 将这里改掉:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 

自定义委托

相关内容可以查看:

UE4/5C++:Delegate(委托or代理?)的使用_多方通行8的博客-CSDN博客

在子系统创建自定义委托

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 然后在下面:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 

(这里的红线是说找不到,并不需要在意,如果这个时候启动或者热更新仍然是可以使用的,说明这是对的,如果看这个不爽,老办法:删除binary等文件)

接下来我们来到菜单的头文件:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 

然后声明。

因为我们要绑定到委托,所以这个委托应该是在MenuSet中就进行绑定:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 之后,我们到子系统里面:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 这样可以进行测试:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 

不过我们如果在这里测试的话,会发现直接就跳转到了另一个世界,并没有打印出这些字。

因为在执行这里之前,我们就已经跳转到另一个世界里了。

调整位置

这里我们需要将调整世界的函数换一个地方,我是希望在所有回调函数执行后在执行这个,所以要把这个红圈里面的ctrl+x换一个地方:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 

所以我们放在打印完毕之后(狗头笑容)

并且底下加一个如果创建失败的情况:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 测试:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 

创建更多的委托和回调函数给菜单:

因为子系统无法将相应的东西返回菜单类

所以我们在子系统里面,做一些自定义委托

多播和动态多播

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

//自定义委托,用于回调到菜单类
//动态多播
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiOnCreateSessionComplete, bool, bWasSuccessful);
//这里使用多播,而不是动态多播
DECLARE_MULTICAST_DELEGATE_TwoParams(FMultiOnFindSessionComplete, const TArray<FOnlineSessionSearchResult>& SessionResult, bool bWasSuccessful);
DECLARE_MULTICAST_DELEGATE_OneParam(FMultiOnJoinSessionComplete, EOnJoinSessionCompleteResult::Type Result);
//动态多播
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiOnDestroySessionComplete, bool, bWasSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiOnStartSessionComplete, bool, bWasSuccessful);

委托变量

然后在之前创建委托变量的地方:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

FMultiOnCreateSessionComplete MultiPlayerOnCreateSessionComplete;
FMultiOnFindSessionComplete  MultiPlayerOnFindSessionComplete;
FMultiOnJoinSessionComplete  MultiPlayerOnJoinSessionComplete;
FMultiOnDestroySessionComplete  MultiPlayerOnDestroySessionComplete;
FMultiOnStartSessionComplete  MultiPlayerOnStartSessionComplete;

回调函数

然后是回调函数:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

UFUNCTION()
	void onCreateSession(bool bWasSuccessful);
	void onFindSession(const TArray<FOnlineSessionSearchResult>& SessionResult, bool bWasSuccessful);
	void onJoinSession(EOnJoinSessionCompleteResult::Type Result);
	UFUNCTION()
	void onDestroySession(bool bWasSuccessful);
	UFUNCTION()
	void onStartSession(bool bWasSuccessful);

绑定委托和动态函数:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

MultiPlayerSessionSubsystem->MultiPlayerOnCreateSessionComplete.AddDynamic(this, &ThisClass::onCreateSession);
		MultiPlayerSessionSubsystem->MultiPlayerOnFindSessionComplete.AddUObject(this, &ThisClass::onFindSession);
		MultiPlayerSessionSubsystem->MultiPlayerOnJoinSessionComplete.AddUObject(this, &ThisClass::onJoinSession);
		MultiPlayerSessionSubsystem->MultiPlayerOnDestroySessionComplete.AddDynamic(this, &ThisClass::onDestroySession);
		MultiPlayerSessionSubsystem->MultiPlayerOnStartSessionComplete.AddDynamic(this, &ThisClass::onStartSession);

头文件添加

在菜单的cpp文件中添加头文件:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

#include "OnlineSessionSettings.h"
#include "Interfaces/OnlineSessionInterface.h"

实现加入按钮:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 

实现寻找函数:

首先在子系统的头文件中,做一个智能指针

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 制作完毕之后,在cpp中开始实现这个find函数(这个不是回调函数):

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

void UMultiPlayerSessionGISubsystem::FindSession(int32 findSessionMaxNum)
{
	if (!mySessionInterface.IsValid())
	{
		return;
	}
	//会话接口委托列表添加委托,然后句柄获取
	FindSessionsCompleteDelegateHandle = mySessionInterface->AddOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate);

	LastSessionSearch = MakeShareable(new FOnlineSessionSearch);
	//配对服务返回的查询的最大数目
	LastSessionSearch->MaxSearchResults = findSessionMaxNum;
	//查询是否用于局域网匹配
	LastSessionSearch->bIsLanQuery = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true : false;
	//SEARCH_PRESENCE :仅搜索存在会话(值为true/false)
	//QuerySettings :用于查找匹配服务器的查询
	LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
	//获取本地的玩家控制器
	const ULocalPlayer* playerControler = GetWorld()->GetFirstLocalPlayerFromController();
	//搜索与指定匹配的对话
	//GetPreferredUniqueNetId :检索首选的唯一网id。这是为了向后兼容不使用缓存唯一网络id逻辑的游戏
	if (!mySessionInterface->FindSessions(*playerControler->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef());)
	{
		//寻找失败
		//清除
		mySessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle);
		//因为失败了,所以传入的是一个空的数组和false
		MultiPlayerOnFindSessionComplete.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
	}
}

实现寻找的回调函数

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

void UMultiPlayerSessionGISubsystem::onFindSessionComplete(bool bWasSuccessful)
{
	if (mySessionInterface)
	{
		//清除
		mySessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle);
	}
	//查找的会话数量
	if (LastSessionSearch->SearchResults.Num()<=0)
	{
		//因为失败了,所以传入的是一个空的数组和false
		MultiPlayerOnFindSessionComplete.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
		return;
	}
	//传入菜单
	MultiPlayerOnFindSessionComplete.Broadcast(LastSessionSearch->SearchResults, bWasSuccessful);
}

菜单类的onfind回调函数

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

void UInPluginsMenu::onFindSession(const TArray<FOnlineSessionSearchResult>& SessionResult, bool bWasSuccessful)
{
	if (MultiPlayerSessionSubsystem == nullptr)
	{
		return;
	}
	//遍历找到的会话数组
	for (auto Result : SessionResult)
	{
		FString SettingsValue;
		//获取定义会话设置的key对应的value赋予SettingsValue
		Result.Session.SessionSettings.Get(FName(TEXT("MatchType")), SettingsValue);
		if (SettingsValue ==MatchType)//判断SettingsValue和MatchType是否一致,即找到了会话
		{
			//加入会话(在这里)
			MultiPlayerSessionSubsystem->JoinSession(Result);
			return;
		}
	}
}

加入会话函数:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

void UMultiPlayerSessionGISubsystem::JoinSession(const FOnlineSessionSearchResult& SessionResult)
{
	if (!mySessionInterface.IsValid())
	{
		//无效情况下
		//广播到所有绑定对象:UnknownError
		MultiPlayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
		return;
	}
	//获取句柄和委托列表添加
	JoinSessionCompleteDelegateHandle =mySessionInterface->AddOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate);
	//加入会话
	const ULocalPlayer* localPlayer = GetWorld()->GetFirstLocalPlayerFromController();
	if (!mySessionInterface->JoinSession(*localPlayer->GetPreferredUniqueNetId(), NAME_GameSession, SessionResult))
	{
		//加入失败
		//清除委托
		mySessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
		//广播回调函数为未知错误
		MultiPlayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
	}
}

加入会话的回调函数:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

void UMultiPlayerSessionGISubsystem::onJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
	if (mySessionInterface)
	{
		//执行完成,所以清除一下
		mySessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
	}
	//广播到菜单的onjoinsession
	MultiPlayerOnJoinSessionComplete.Broadcast(Result);
}

菜单内的加入回调函数

菜单cpp中添加头文件:

#include "OnlineSubsystem.h"	

然后

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码:

void UInPluginsMenu::onJoinSession(EOnJoinSessionCompleteResult::Type Result)
{
	IOnlineSubsystem* onlineSubsystem = IOnlineSubsystem::Get();
	if (onlineSubsystem)
	{
		//临时接口
		IOnlineSessionPtr TempMySessionInterface = onlineSubsystem->GetSessionInterface();
		if (TempMySessionInterface.IsValid())
		{
			//给予tempAddress地址
			FString tempAddress;
			TempMySessionInterface->GetResolvedConnectString(NAME_GameSession,tempAddress);
			//从游戏实例里面获取本地的第一个玩家控制器
			APlayerController* playerControler = GetGameInstance()->GetFirstLocalPlayerController();
			if (playerControler)
			{
				//世界跳跃
				//旅行到不同的地图或IP地址。
				//在执行任何操作之前调用PreClientTravel事件。
				playerControler->ClientTravel(tempAddress, ETravelType::TRAVEL_Absolute);
			}
		}
	}
}

防止可能出现的意外进行的添加:

在菜单头文件添加这个头文件:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码1:

#include "Interfaces/OnlineSessionInterface.h"

在子系统创建会话这里加这两个:

ue4 fonlinesessionsearchresult,# ue4/5多人游戏插件制作,ue4,游戏,ue5,c++,网络

 代码2:

//用于防止不同的构建在搜索期间看到彼此
	LastSessionSettings->BuildUniqueId = 1;
	//支持api则使用
	LastSessionSettings->bUseLobbiesIfAvailable = true;

测试结果是可以连接的(不过创建会话的时候需要等待一会儿,让steam完全连接(加入会话也是一样))文章来源地址https://www.toymoban.com/news/detail-766452.html

到了这里,关于UE4/5多人游戏详解(七、自定义委托,实现寻找会话和加入会话的函数,通过Steam进行两台电脑的联机)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • UE4/5C++:Delegate(委托or代理?)的使用

    目录 DECLARE的使用 单播: 绑定UObject 绑定 调用 无参调用 解除绑定: 绑定Lambda表达式: 绑定c++原生的c++类的函数: 绑定共享指针: 绑定静态函数: 绑定线程安全的共享指针: 绑定一个Function方法: 多播 动态单播代理:  用在蓝图上: 在c++中如何绑定:  动态多播代理  

    2024年02月07日
    浏览(83)
  • 【UE4】多人联机教程(重点笔记)

    1. 创建房间、搜索房间功能 2. 根据指定IP和端口加入游戏 1. 新建一个第三人称角色模板工程 2. 创建一个空白关卡,这里命名为“InitMap” 3. 新建一个控件蓝图,这里命名为“UMG_ConnectMenu” 在关卡蓝图中显示该控件蓝图 打开“UMG_ConnectMenu”,添加如下控件 首先添加创建房间按

    2024年02月14日
    浏览(54)
  • UE4C++之动态多播委托的简单使用

    本文讲述一下动态多播委托的简单使用,包括它的声明,定义,在蓝图中的使用。 我这边使用的前提是在创建了一个属性组件,添加到角色中,当角色收到血量改变的通知的时候,会进行相应的处理。 定义变量,注意在public权限内使用,因为外部会引用到。BlueprintAssignable标

    2024年02月13日
    浏览(43)
  • UE4 中可全局获取的变量(例如游戏实例、玩家控制器等) 详解

    🙋‍♂️ 作者:海码007 📜 专栏:UE虚幻引擎专栏 💥 标题:UE4 中可全局获取的变量(例如游戏实例、玩家控制器、游戏模式等) 详解 ❣️ 寄语:加油,一次专注一件事! 🎈 最后: 文章作者技术和水平有限,如果文中出现错误,希望大家能指正,同时有问题的话,欢迎

    2024年02月06日
    浏览(112)
  • UE4自定义资产类型编辑器实现

    在虚幻引擎中,资产是具有持久属性的对象,可以在编辑器中进行操作。 Unreal 附带多种资源类型,从 UStaticMesh 到 UMetasoundSources 等等。 自定义资源类型是实现专门对象的好方法,这些对象需要专门构建的编辑器来进行高效操作。 通过在插件中实现这些类型,它们可以在项目

    2024年02月11日
    浏览(52)
  • ue4中使用c++实现自定义网格体

    有两个类可以在ue4中实现自定义网格体,分别是UCustomMeshComponent和UProceduralMeshComponent,实现的方法都是构建三角形以实现不同的网格体。 网上的教程以蓝图为主,但我想用c++实现。 我找到了一篇用UProceduralMeshComponent实现的博客,链接如下:https://blog.csdn.net/yb0022/article/details

    2024年02月07日
    浏览(43)
  • 【UE5 多人联机教程】04-加入游戏

    1. 新建一个控件蓝图,父类为“USC_Button_Standard”  控件蓝图命名为“UMG_Item_Room”,用于表示每一个搜索到的房间的界面 打开“UMG_Item_Room”,在图表中新建一个变量,命名为“Session”  变量类型为“蓝图会话结果”,选择可编辑实例和生成时公开 2. 打开“UMG_MainMenu”,添加

    2024年02月15日
    浏览(64)
  • UE4动作游戏实例RPG Action解析三:实现效果,三连击Combo,射线检测,显示血条,火球术

    实现武器三连击,要求: 1.下一段Combo可以随机选择, 2.在一定的时机才能再次检测输入 3. 等当前片段播放完才播放下一片段 1.1、蒙太奇设置 通过右键-新建蒙太奇片段,在蒙太奇里创建三个片段,并且移除相关连接,这样默认只会播放第一个片段 不同片段播放动画从 资产

    2024年02月21日
    浏览(55)
  • UE4游戏保存

    在游戏运行过程中由于某些事情需要暂停一下游戏,那就需要把游戏当前的进度保存起来,下次打开的时候还可以再次玩,我们这里主要保存的就是。所有需要有一个游戏保存的机制。UE4提供了这样的机制。 首先新建一个类继承在SaveGame,命名为FirstSaveGame 打开VS2019编辑代码

    2024年02月12日
    浏览(56)
  • ue4游戏dump

    链接 UE4Dumper:https://github.com/kp7742/UE4Dumper 游戏示例: https://www.bilibili.com/video/BV12v41167Gy 定义 GWorld 指向游戏世界对象 GNames 指向游戏字符串数组 GUObject 指向游戏对象数组 UE4版本 查看AndroidManifest.xml 游戏版本为 U E 4 + R e l e a s e - 4 . 2 5 指针怎么找 GWorld 切换到Exports 搜索【

    2024年02月04日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包