Vivox Unity SDK 16.0.0 升级指南
Upgrade from previous Vivox versions to version 16.0.0.
阅读时间9 分钟最后更新于 7 个月前
本指南详细介绍如何升级到 Vivox Unity SDK 版本 16.0.0,并重点讨论两个 SDK 版本之间的差异。
版本 16.0.0 推出了简化的功能,并在以下相关方面也进行了更改:
- SDK 初始化
- 登录/注销
- 屏蔽玩家
- 连接到频道
- 频道参与者管理
- 音频设备管理
- 设置活动设备
- 设置设备增益/音量
- 设备静音
SDK 设置和初始化
将 替换为 以访问 Vivox API。
using VivoxUnity;using Unity.Services.Vivox;VivoxUnity 命名空间不再存在。
此外,客户端(用于初始化 SDK 的原始方式)已不复存在。
使用 Authentication
如果您使用的是 Unity Authentication 包,请依次调用 、、,如以下示例所示:
await UnityServices.InitializeAsync()await AuthenticationService.Instance.SignInAnonymously()await VivoxService.Instance.InitializeAsync()async void InitializeAsync(){ await UnityServices.InitializeAsync(); await AuthenticationService.Instance.SignInAnonymouslyAsync(); await VivoxService.Instance.InitializeAsync();}
还可以使用 提供的任何其他登录选项。
AuthenticationService.Instance如果项目使用 Unity Dashboard(Unity 后台)凭据但未使用 AuthenticationService 包,则可以启用测试模式并省略 登录调用。要打开测试模式,请在 Unity 编辑器中转到 Project Settings > Services > Vivox 并选中标有 Test Mode 的框。
AuthenticationService以下示例显示了未使用 AuthenticationService 包但启用了测试模式的初始化设置:
async void InitializeAsync(){ await UnityServices.InitializeAsync(); await VivoxService.Instance.InitializeAsync();}
使用 Vivox 开发者门户凭据
如果您有旧版 Vivox 开发者门户凭据,请通过 向 提供这些凭据。这些凭据可以包含用于测试目的的签名密钥。
InitializationOptionsVivoxService.Instance.InitializeAsync以下示例显示了使用 Vivox 开发者门户凭据的初始化设置:
async void InitializeAsync(){ InitializationOptions options = new InitalizationOptions(); // _key can be excluded from SetVivoxCredentials if an implementation of IVivoxTokenProvider has been provided to the SDK. options.SetVivoxCredentials(_server, _domain, _issuer, _key); await UnityServices.InitializeAsync(options); await VivoxService.Instance.InitializeAsync();}
登录生命周期更改
ILoginSession.BeginLoginVivoxService.Instance.LoginAsync(LoginOptions options = null)LoginOptions- DisplayName
- 启用文本转语音
- 加入新频道时禁用自动频道传输交换
- 缓存登录时要为当前玩家屏蔽(交叉静音)的 PlayerID 列表
- 设置 SDK 接收参与者更新事件的速率
async void LoginToVivoxAsync(List<string> blockedList, string displayName){ LoginOptions options = new LoginOptions(); options.DisplayName = displayName; options.BlockedUserList = blockedList; await VivoxService.Instance.LoginAsync(options);}
ILoginSession.Logout()VivoxService.Instance.LogoutAsync将任何绑定到 事件的逻辑(其 PropertyName 为“State”)和 或 都移动到其他函数。拆分 login 和 logout 的逻辑以分别在 和 上触发,如以下示例所示。
LoginSession.PropertyChangedLoginState.LoggedInLoginState.LoggedOutVivoxService.Instance.LoggedInVivoxService.Instance.LoggedOutvoid Start(){ VivoxService.Instance.LoggedIn += OnUserLoggedIn; VivoxService.Instance.LoggedOut += OnUserLoggedOut;}void OnDestroy(){ //Cleanup events if the GameObject is destroyed to prevent unexpected behavior. VivoxService.Instance.LoggedIn -= OnUserLoggedIn; VivoxService.Instance.LoggedOut -= OnUserLoggedOut;}void OnUserLoggedIn(){ Debug.Log("The user has successfully logged in"); // Other logic such as attempting a default channel join or changing the state of voice UIs to indicate the character is logged in can be done here.}void OnUserLoggedOut(){ Debug.Log("The user has logged out"); // The LoggedOut event will fire after a VivoxService.Instance.LogoutAsync call has been completed successfully // or after an internet disruption has caused Automatic Connection Recovery to declare the attempted recovery a failure.}
屏蔽玩家
ILoginSession.SetCrossMutedCommunicationsVivoxServince.Instance.BlockPlayerAsync(string playerId)VivoxService.Instance.UnblockPlayerAsync(string playerId)playerIdAccountId频道生命周期更改
加入和离开频道
所有与 相关的逻辑都已替换为以下方法:
ChannelSession.BeginConnectJoinGroupChannelAsync(string channelName, ChatCapability chatCapability, ChannelOptions channelOptions = null);JoinPositionalChannelAsync(string channelName, ChatCapability chatCapability, Channel3DProperties positionalChannelProperties, ChannelOptions channelOptions = null);JoinEchoChannelAsync(string channelName, ChatCapability chatCapability, ChannelOptions channelOptions = null);
ChannelSession.Disconnect()- ,用于离开特定频道。
VivoxService.Instance.LeaveChannelAsync(string channelName) - ,用于离开所有活动频道。如果任何时候只加入一个频道,我们建议使用此方法。
VivoxService.Instance.LeaveAllChannelsAsync()
ILoginSession.ChannelSessionsVivoxService.Instance.ActiveChannelsVivoxService.Instance.ActiveChannelsVivoxParticipants以前在实现中依赖 和 来确定用户是否已连接到频道。现在已将跟踪这两个属性的状态更改的事件替换为与 和 相关的函数。
AudioStateTextStateVivoxService.Instance.ChannelJoinedVivoxService.Instance.ChannelLeftVivoxService.Instance.ChannelJoinedVivoxService.Instance.ChannelLeft以下代码示例是这些更改的示例:
void BindToChannelActions(){ //Connecting/Disconnecting channel actions can be done upon VivoxService.Instance.LoggedIn and LoggedOut events being fired, respectively, //for basic lifecycle control VivoxService.Instance.ChannelJoined += OnChannelJoined; VivoxService.Instance.ChannelLeft += OnChannelLeft;}void UnbindChannelActions(){ VivoxService.Instance.ChannelJoined -= OnChannelJoined; VivoxService.Instance.ChannelLeft -= OnChannelLeft;}void OnChannelJoined(string channelName){ //The channel with name channelName has been successfully joined, and any UI updates should be done for it //Additionally, if multiple channels are being handled, keeping track of the channelName and knowing which channel is for which purpose should be done //on the side of the implementation based on this event.}void OnChannelLeft(string channelName){ //The channel with name channelName has been successfully left, and any UI updates should be done for it //This also means that the channelName can likely be safely lost, although if the channelName is specific and might be rejoined, //it should be held on to by the implementation.}
频道传输
默认情况下,频道传输(语音进入的频道)切换到最近加入的频道。若要禁用此功能,可在使用该 LoginOptions 对象作为输入调用 之前将 设置为 true。
VivoxService.Instance.LoginAsyncLoginOptions.DisableAutomaticChannelTransmissionSwap可以使用 方法手动更改频道传输模式。
VivoxService.Instance.SetChannelTransmissionModeAsync(TransmissionMode transmissionMode, string channelName = null)此 API 可以根据该方法的输入,将传输频道设置为特定频道、所有频道或无任何传输频道。
频道参与者管理
VivoxParticipant 已取代 ChannelParticipant。
如果使用了正确的键(频道名称),可以通过从 索引中获取值来访问每个活动频道的 VivoxParticipant 集合。
VivoxService.Instance.ActiveChannels使用 和 可以了解何时在频道中添加或移除了 VivoxParticipant。
VivoxService.Instance.ParticipantAddedToChannelVivoxServince.Instance.ParticipantRemovedFromChannel这些事件将提供相关的 VivoxParticipant 作为绑定到这些事件的任何回调的输入。VivoxParticipant 对象包含参与者的 PlayerId、参与者加入或离开的频道名称以及其他有价值的信息,包括参与者是否为本地玩家或玩家的显示名称。以下示例显示了这些类型的事件:
void BindToParticipantEvents(){ //These events can be connected at the same time as the channel events from the previous sections for convenience purposes VivoxService.Instance.ParticipantAddedToChannel += OnParticipantAdded; VivoxService.Instance.ParticipantRemovedFromChannel += OnParticipantRemoved;}void UnbindParticipantEvents(){ VivoxService.Instance.ParticipantAddedToChannel -= OnParticipantAdded; VivoxService.Instance.ParticipantRemovedFromChannel -=OnParticipantRemoved;}void OnParticipantAdded(VivoxParticipant participant){ // Use VivoxParticipant to establish some UI element tied to that specific VivoxParticipant, which can then be used to control things such as muting // volume, and blocking, along with UI that can track certain states - such as whether the player is currently muted or is currently speaking.}void OnParticipantRemoved(VivoxParticipant participant){ // At this point, any UI created to display information about this VivoxParticipant can be safely disposed of.}
VivoxParticipant 对象
VivoxParticipant- ,指明参与者是否代表本地玩家。
VivoxParticipant.IsSelf - ,指明参与者的音频能量是否超过了 Vivox SDK 将音频视为语音的阈值。
VivoxParticipant.SpeechDetected
VivoxParticipant 还包含以下事件:
ParticipantMuteStateChangedParticipantSpeechDetectedParticipantAudioEnergyChanged
这些事件可用于创建功能音量单位 (VU) 计量表或语音指示器。请在每个参与者的单个 UI 级别连接这些事件。
以下示例类是 ChatChannelSample 中的 RosterItem 的简化版本:
public class RosterItem : MonoBehaviour{ public VivoxParticipant Participant; public Text PlayerNameText; public void SetupRosterItem(VivoxParticipant participant) { Participant = participant; PlayerNameText.text = Participant.DisplayName; Participant.ParticipantMuteStateChanged += OnMuteStateChanged; Participant.ParticipantSpeechDetected += OnSpeechDetected; } void OnMuteStateChanged() { if(Participant.IsMuted) { //Participant has been muted } else { //Participant has been unmuted } } void OnSpeechDetected() { //Participant AudioEnergy has exceeded the value required to be considered speech }}
将频道参与者静音
VivoxParticipant.MutePlayerLocally()VivoxParticipant.UnmutePlayerLocally()音频设备管理
设备管理不再通过利用 Client 对象来实现。现在可以进行任何设备调整,例如静音、更改音量或使用 切换活动设备。
VivoxService.Instance将本地玩家静音
本地玩家静音已更改为使用 和 函数,而不必通过 IAudioDevice 对象上的 API 或将频道传输切换为 none 来实现此目的。这些 API 会将本地用户的输入设备静音或取消静音。
VivoxService.Instance.MuteInputDevice()VivoxService.Instance.UnmuteInputDevice()调节输入/输出设备音量
现在可以使用 和 来调整设备音量。
VivoxService.Instance.SetInputDeviceVolume(int value)VivoxService.Instance.SetOutputDeviceVolume(int value)更改活动输入/输出设备
可以通过调用 或 来调整活动输入/输出设备。
VivoxService.Instance.SetActiveOutputDeviceAsync(VivoxOutputDevice device)VivoxService.Instance.SetActiveInputDeviceAsync(VivoxInputDevice device)可以通过访问属性 和 来获取 和 的集合。
VivoxService.Instance.AvailableInputDevicesVivoxService.Instance.AvailableOututDevicesVivoxInputDevicesVivoxOutputDevices以下示例演示如何使用 Vivox SDK 音频设备 API 来填充输入设备的下拉列表,而该列表可用于更改活动输入设备。
using System.Linq;using Unity.Services.Vivox;using UnityEngine;using UnityEngine.UI;public class AudioDeviceSettings : MonoBehaviour{ public Dropdown InputDeviceDropdown; private void Start() { VivoxService.Instance.AvailableInputDevicesChanged += RefreshInputDeviceList; InputDeviceDropdown.onValueChanged.AddListener((i) => { InputDeviceValueChanged(i); }); } void OnEnable() { RefreshInputDeviceList(); } void OnDestroy() { // Unbind all UI actions InputDeviceDropdown.onValueChanged.RemoveAllListeners(); VivoxService.Instance.AvailableInputDevicesChanged -= RefreshInputDeviceList; } private void RefreshInputDeviceList() { InputDeviceDropdown.Hide(); InputDeviceDropdown.ClearOptions(); InputDeviceDropdown.options.AddRange(VivoxService.Instance.AvailableInputDevices.Select(v => new Dropdown.OptionData() { text = v.DeviceName })); InputDeviceDropdown.SetValueWithoutNotify(InputDeviceDropdown.options.FindIndex(option => option.text == VivoxService.Instance.ActiveInputDevice.DeviceName)); InputDeviceDropdown.RefreshShownValue(); } void InputDeviceValueChanged(int index) { VivoxService.Instance.SetActiveInputDeviceAsync(VivoxService.Instance.AvailableInputDevices.Where(device => device.DeviceName == InputDeviceDropdown.options[index].text).First()); }}