diff --git a/Assets/Scripts/EOSVoiceChat.cs b/Assets/Scripts/EOSVoiceChat.cs index f330a45..76f4675 100644 --- a/Assets/Scripts/EOSVoiceChat.cs +++ b/Assets/Scripts/EOSVoiceChat.cs @@ -12,7 +12,7 @@ using UnityEngine; /// This class does not know anything about EOS platform initialization or authentication; it just takes the required /// EOS interfaces and exposes a number of game-related voice functions. /// -public class EOSVoiceChat +public class EOSVoiceChat: IDisposable { private const uint DefaultMaxChatPlayers = 16; // "Lobbies that generate conference rooms must have <= 16 max players" @@ -27,6 +27,10 @@ public class EOSVoiceChat private string rtcRoomName; public bool IsConnected => lobbyInterface != null && rtcInterface != null && audioInterface != null && !string.IsNullOrEmpty(connectedLobbyId); + private string defaultInputDeviceId; + public bool HasInputDevice => !string.IsNullOrEmpty(defaultInputDeviceId); + + private ulong? onAudioDevicesChangedCallbackId; private ulong? onConnectionChangedCallbackId, onParticipantStatusChangedCallbackId, onParticipantUpdatedCallbackId; /// @@ -41,6 +45,14 @@ public class EOSVoiceChat this.rtcInterface = rtcInterface; this.audioInterface = audioInterface; this.localUserProvider = localUserProvider; + + SubscribeToAudioDeviceNotifications(); + } + + public void Dispose() + { + DisconnectChat(); + UnsubscribeFromAudioDeviceNotifications(); } /// @@ -282,6 +294,48 @@ public class EOSVoiceChat // TODO: handle input/output device changes (keep track of current devices) + private void SubscribeToAudioDeviceNotifications() + { + var localUserId = localUserProvider.Invoke(); + + if (!onAudioDevicesChangedCallbackId.HasValue) + { + onAudioDevicesChangedCallbackId = audioInterface.AddNotifyAudioDevicesChanged( + new AddNotifyAudioDevicesChangedOptions(), null, + HandleAudioDevicesChanged); + + // Call the event handler once to query the audio devices in their initial state + HandleAudioDevicesChanged(null); + } + } + + private void UnsubscribeFromAudioDeviceNotifications() + { + if (onAudioDevicesChangedCallbackId.HasValue) + { + audioInterface.RemoveNotifyAudioDevicesChanged(onAudioDevicesChangedCallbackId.Value); + onAudioDevicesChangedCallbackId = null; + } + } + + private void HandleAudioDevicesChanged(AudioDevicesChangedCallbackInfo data) + { + defaultInputDeviceId = null; + + // Update the default input device, so we know whether we can actually talk or not + uint inputDevicesCount = audioInterface.GetAudioInputDevicesCount(new GetAudioInputDevicesCountOptions()); + for (uint inputDeviceIndex = 0; inputDeviceIndex < inputDevicesCount; ++inputDeviceIndex) + { + var inputDeviceInfo = audioInterface.GetAudioInputDeviceByIndex( + new GetAudioInputDeviceByIndexOptions { DeviceInfoIndex = inputDeviceIndex }); + + if (inputDeviceInfo.DefaultDevice) + { + defaultInputDeviceId = inputDeviceInfo.DeviceId; + } + } + } + private void SubscribeToRoomNotifications() { var localUserId = localUserProvider.Invoke(); @@ -370,11 +424,11 @@ public class EOSVoiceChat switch (data.ParticipantStatus) { case RTCParticipantStatus.Joined: - if (chatUsers.ContainsKey(data.ParticipantId)) - return; - - var chatUser = new ChatUser(data.ParticipantId); - chatUsers.Add(data.ParticipantId, chatUser); + if (!chatUsers.ContainsKey(data.ParticipantId)) + { + var chatUser = new ChatUser(data.ParticipantId); + chatUsers.Add(data.ParticipantId, chatUser); + } break; case RTCParticipantStatus.Left: chatUsers.Remove(data.ParticipantId); diff --git a/Assets/Scripts/MagnificentVoiceChat.cs b/Assets/Scripts/MagnificentVoiceChat.cs index 74d9ff8..6e4d240 100644 --- a/Assets/Scripts/MagnificentVoiceChat.cs +++ b/Assets/Scripts/MagnificentVoiceChat.cs @@ -234,7 +234,7 @@ public class MagnificentVoiceChat : MonoBehaviour { if (voiceChat != null) { - voiceChat.DisconnectChat(); + voiceChat.Dispose(); voiceChat = null; }