玩家可以利用语音通信快速轻松地相互通信。通过 EOS语音聊天(EOS Voice Chat) 插件,开发人员可以利用 Epic在线服务(Epic Online Services)(EOS)语音接口向其产品添加语音通信,包括使用引擎的 在线子系统(Online Subsystem)(OSS)中熟悉的IVoiceChat和IVoiceChatUser接口。此外,之前使用VivoxVoiceChat的开发人员可以轻松迁移到EOS后端。
设置
EOS语音聊天插件实现了IVoiceChat和IVoiceChatUser接口。首先,从编辑器的 编辑(Edit) 菜单打开 插件浏览器(Plugin Browser),然后查找并启用该插件。
在你的项目中启用该插件后,你可以通过 大厅(Lobbies) 方法或 可信服务器(Trusted Server) 方法将其集成。这些方法并不互斥;你可以混合使用,获得每种方法的好处和功能。
尽管两种方法都基于EOS的工作方式,但你不需要直接使用EOS SDK来编程。但是,如果你想更好地理解其工作原理,可以阅读EOS语音接口文档。阅读时,请注意,IVoiceChat 通道(Channels) 等效于EOS房间(Rooms),并且这两个术语应视为可互换。
与EOS语音接口集成
“大厅”和“可信服务器”这两种主要的集成方法提供了不同的功能。我们建议你考虑哪种方法更适合你的项目,或者考虑是否混合方法的效果最佳。利用“大厅”方法,系统将通过EOS自动加入语音聊天,而无需 IVoiceChatUser::JoinChannel 功能,并且你将从EOS收到一个IVoiceChatUser实例。“可信服务器”方法要求你使用来自可信服务器的凭证调用 IVoiceChatUser::JoinChannel 函数,不过好处是,你可以选择要加入或离开哪些通道。此方法还允许你控制你的IVoiceChat和IVoiceChatUser实例,而不是要求你使用EOS提供的实例。如果你想要OnlineSubsystemEOS插件自动管理大厅语音通道,同时你通过IVoiceChat和IVoiceChatUser接口手动管理可信服务器通道,则可以混合使用这两种集成方法。若开发人员采取混合集成方法,则还可以利用用户已通过“可信服务器”方法加入的通道,复用“大厅”方法中的IVoiceChatUser实例。
首先,你将需要在EOS开发人员门户上配置你的应用程序。如果你使用的是“大厅”集成方法,还需要在项目中启用 OnlineSubsystemEOS 插件。
使用“大厅”方法
“大厅”方法会利用EOS来处理加入通道时所涉及的大部分工作。这意味着,使用此集成方法并不需要实现通常的IVoiceChat流程来初始化、连接、登录和加入通道,因为EOS将为你执行相应操作。
对你的项目设置OnlineSubsystemEOS后,您将能够加入并托管EOS大厅会话。执行以下步骤,启用对应语音通道的自动加入:
-
找到EOS开发人员描绘,然后配置你的应用程序,在其中启用语音支持。
-
在创建大厅会话时,将
FOnlineSessionSettings::bUseLobbiesVoiceChatIfAvailable设置为true。 -
调用
FOnlineSubsystemEOS::GetVoiceChatUserInterface以获得与给定本地用户关联的IVoiceChatUser接口实例。
用户登录EOS后,你可以使用 GetVoiceChatUserInterface 函数获得IVoiceChatUser接口的实例。尽管你不需要管理通道,但你可以使用此实例与系统的其他方面交互,如用户的选定输入和输出设备,或其玩家屏蔽列表。使用此接口实例注册事件通知回调。只要用户保持登录状态,OnlineSubsystemEOS插件将自动加入和离开用户加入或离开的任意大厅的关联语音通道。与此同时,EOSVoiceChat将广播 OnVoiceChatChannelJoined 和 OnVoiceChatChannelExited 委托作为响应。
OnlineSubsystemEOS插件将使用有关大厅会话的信息自动更新EOS语音聊天插件,这些信息包括有关创建、销毁、加入和离开大厅会话的通知。EOS语音聊天插件将广播 OnVoiceChatChannelJoined 和 OnVoiceChatChannelExited 委托以响应这些事件。
使用可信服务器方法
对于偏好手动通道管理的情况,你将需要使用“可信服务器”集成方法。例如,你使用的聚会系统不是在EOS大厅上构建的,那么你将需要此方法为你的聚会创建通道。“可信服务器”方法提供了对用户的通道连接的更大控制权,但它要求用户从可信服务器检索登录凭证才能加入通道。
可信服务器引擎配置
如果你要复用“大厅”集成中的IVoiceChatUser接口实例,就可以跳过此分段。
如果你不使用“大厅”集成,或者想使用单独的IVoiceChatUser接口实例,就需要将以下分段添加到你的 Engine.ini 文件,并填充你的产品信息:
[EOSVoiceChat]
ProductId=
SandboxId=
DeploymentId=
ClientId=
ClientSecret=
使用你的产品的相应值填写每行。你可以在EOS开发人员门户上打开你的产品,找到这些值。EOSVoiceChat会使用这些值创建EOS平台接口实例。
代码流程
创建你自己的IVoiceChat和IVoiceChatUser实例时,你需要遵循IVoiceChat生命周期。此周期的基本流程始于获取和初始化IVoiceChat实例,并使用该实例为每个本地玩家创建IVoiceChatUser实例。你可以利用该实例自由地手动进入和离开所有可信服务器通道,并且用户可以通过EOS与其他用户通信。完成所有语音通信之后,通常是在应用程序关闭期间,你必须取消初始化你创建的全部实例。此流程涉及以下函数,它们必须按顺序调用。
对于你在“可信服务器”集成方法中创建的实例,此流程是必需的。如果你的项目使用这两种集成方法,并且你要将OSS EOS中的一个或多个IVoiceChatUser实例复用于可信服务器通道,那么这些要求不适用;“大厅”集成会自动处理IVoiceChat流程的大部分工作(包括实例生命周期管理),并提供登录的IVoiceChatUser实例。
| 函数 | 用法 |
|---|---|
IVoiceChat::Initialize |
初始化IVoiceChat实例。你必须对你创建的所有实例调用此函数,然后才能使用该实例。 |
IVoiceChat::Connect |
连接到预配置的语音服务器。 |
IVoiceChat::CreateUser |
创建IVoiceChatUser接口实例。打算加入通道的每个本地用户都需要其自己的实例才能登录。与此流程中的其他函数不同,你可以随时调用 CreateUser。 |
IVoiceChatUser::Login |
将本地用户登录到语音聊天服务器。PlayerName 参数是用户的EOS产品ID,使用 EOS_ProductUserId_ToString API进行了字符串化,并使用UTF8_TO_TCHAR或类似方法转换为了FString。不要求相关的EOS Product ID通过连接接口登录(EOSVoiceChat使用的平台实例的连接接口),只要求它是一个有效的EOS Product ID。所需的授权由受信服务器以“通道加入凭证”的形式加入,然后传递给 IVoiceChatUser::JoinChannel。 |
IVoiceChatUser::JoinChannel |
登录到服务器后加入通道。用户一次可以加入多个通道,并且可以在离开后重新加入通道;每个通道将从此刻开始继续单独遵循该流程。此过程需要凭证;请参阅下面有关加入通道的小节,了解有关获取凭证的信息。 |
IVoiceChatUser::LeaveChannel |
(可选)导致本地用户离开之前使用 JoinChannel 加入的通道。 |
IVoiceChatUser::Logout |
(可选)将本地用户从语音聊天服务器注销。这样做还会导致该用户离开所有通道。注销后,你可以调用 Login 以重新登录,而无需创建新的接口实例。 |
IVoiceChat::Disconnect |
(可选)从语音服务器断开连接。这样还将实际注销并离开用户已加入的全部通道。 |
IVoiceChat::Uninitialize |
关闭IVoiceChat接口实例。调用此函数还会离开用户已加入的全部通道,注销,并从语音聊天服务器断开连接。此函数通常在应用程序关闭期间调用。 |
(#加入通道)
加入通道
尽管你的代码不需要与EOS SDK交互,但加入通道的过程最终会经过EOS语音接口。如果你想要更好地理解该系统,我们推荐阅读EOS文档站点上的相应文档。
加入通道将需要客户端基本URL和来自你的可信服务器的参与者令牌。填写 FEOSVoiceChatChannelCredentials 结构体并将其序列化为类似于下面示例的JSON,以将此信息提供给EOS语音聊天:
// Create an FEOSVoiceChatChannelCredentials data structure.
FEOSVoiceChatChannelCredentials ChannelCredentials;
// Set the client base URL from the trusted server; this will vary from session to session.
// The URL should look like "wss://example-of-url-us-east-1.rtcp.on.epicgames.com".
ChannelCredentials.ClientBaseUrl = ClientBaseUrlFromTrustedServer
// Set the participant token from the trusted server.
ChannelCredentials.ParticipantToken = ParticipantTokenFromTrustedServer;
// Call JoinChannel with the FEOSVoiceChatChannelCredentials data structure.
VoiceChatUser->JoinChannel(ChannelName, ChannelCredentials.ToJson(), ...);
混合使用“大厅”和“可信服务器”方法
“大厅”和“可信服务器”集成方法彼此完全兼容。如果你想获得这两种方法的优势,可以复用“大厅”方法中的IVoiceChatUser接口来加入、离开你的可信服务器通道并与之交互,也可以创建单独的接口实例。
测试和调试
控制台命令
| 命令 | 说明 |
|---|---|
eosvoicechat list |
列出所有EOSVoiceChat实例及其实例ID、调试名称(有助于辨别这些实例)和创建的用户接口数量。 |
eosvoicechat info instanceid=<instanceid> |
将实例的当前状态和所有关联的用户接口转储到日志中。 |
eosvoicechat initialize instanceid=<instanceid> |
初始化此实例。 |
eosvoicechat uninitialize instanceid=<instanceid> |
取消初始化此实例。 |
eosvoicechat connect instanceid=<instanceid> |
“连接”此实例。这在EOS语音聊天上应该总是会成功,因为EOS语音会处理每个通道的连接。 |
eosvoicechat disconnect instanceid=<instanceid> |
将此实例断开连接。 |
eosvoicechat createuser instanceid=<instanceid> |
创建新的IVoiceChatUser接口。 |
eosvoicechat releaseuser instanceid=<instanceid> |
释放使用 createuser 创建的IVoiceChatUser接口。 |
eosvoicechat createsingleuser instanceid=<instanceid> |
这是适用于非分屏游戏的方便方法。你可以创建单个用户接口,避免在需要它的命令中传递 UserIndex=<UserIndex>。 |
eosvoicechat input setvolume instanceid=<instanceid> userindex=<userindex> volume=<volume> |
设置输入设备的音量。采用0.0到1.0之间的浮点值。 |
eosvoicechat input mute instanceid=<instanceid> userindex=<userindex> |
将输入设备静音。 |
eosvoicechat input unmute instanceid=<instanceid> userindex=<userindex> |
将输入设备取消静音。 |
eosvoicechat input listdevices instanceid=<instanceid> userindex=<userindex> |
列出可用的输入设备。 |
eosvoicechat input setdevice instanceid=<instanceid> userindex=<userindex> deviceid=<deviceid> |
选择特定输入设备。你可以通过 listdevices 命令获取有效 deviceid 值的列表。 |
eosvoicechat input setdefaultdevice instanceid=<instanceid> userindex=<userindex> |
恢复为使用默认输入设备。 |
eosvoicechat output setvolume instanceid=<instanceid> userindex=<userindex> volume=<volume> |
设置输出设备的音量。采用0.0到1.0之间的浮点值。 |
eosvoicechat output mute instanceid=<instanceid> userindex=<userindex> |
将输出设备静音。 |
eosvoicechat output unmute instanceid=<instanceid> userindex=<userindex> |
将输出设备取消静音。 |
eosvoicechat output listdevices instanceid=<instanceid> userindex=<userindex> |
列出可用的输出设备。 |
eosvoicechat output setdevice instanceid=<instanceid> userindex=<userindex> deviceid=<deviceid> |
选择特定输出设备。你可以通过 listdevices 命令获取有效 deviceid 值的列表。 |
eosvoicechat output setdefaultdevice instanceid=<instanceid> userindex=<userindex> |
恢复为使用默认输出设备。 |
eosvoicechat login instanceid=<instanceid> userindex=<userindex> playername=<playername> |
使用户登录此接口。playername 参数是用户的字符串化EOS产品ID。 |
eosvoicechat logout instanceid=<instanceid> userindex=<userindex> |
使用户从此用户接口注销。 |
eosvoicechat channel join instanceid=<instanceid> userindex=<userindex> channelname=<channelname> channeltype=<channeltype> |
加入指定通道。此命令不会向可信服务器查询客户端基本URL或参与者令牌;它将使用配置文件中的 InsecureClientBaseUrl,以及生成的参与者令牌。请参阅 FEOSVoiceChatUser::InsecureGetJoinToken。channeltype 参数是可选的。有一个名为“echo”的反馈通道,对于单用户测试很有用。 |
eosvoicechat channel leave instanceid=<instanceid> userindex=<userindex> channelname=<channelname> |
离开指定通道。 |
eosvoicechat channel transmit instanceid=<instanceid> userindex=<userindex> channelname=<channelname> |
仅传输到特定的指定通道。 |
eosvoicechat channel transmitall instanceid=<instanceid> userindex=<userindex> |
传输到所有通道。 |
eosvoicechat channel transmitnone instanceid=<instanceid> userindex=<userindex> |
不传输到任何通道。 |
eosvoicechat player mute instanceid=<instanceid> userindex=<userindex> playername=<playername> |
将指定远程玩家禁言。尽管你听不到该玩家的声音,该玩家仍可以听到你的声音。要同时停止向其发送输入,请参阅屏蔽命令。 |
eosvoicechat player unmute instanceid=<instanceid> userindex=<userindex> playername=<playername> |
将指定远程玩家取消禁言。 |
eosvoicechat player block instanceid=<instanceid> userindex=<userindex> playername=<playername> |
屏蔽指定远程玩家,使你和该玩家互相听不见。 |
eosvoicechat player unblock instanceid=<instanceid> userindex=<userindex> playername=<playername> |
取消屏蔽指定远程玩家。 |
日志输出
LogEOSVoiceChat 日志类别包含来自EOSVoiceChat插件本身的所有日志输出(包括上述控制台命令),而 LogEOSSDK 日志类别包含来自底层EOS SDK的日志输出。更改 LogEOSSDK 日志类别的冗长度级别还将更新EOS SDK 日志记录接口上的日志冗长度级别设置,因此这两者始终是同步的。