|
|
|
@ -23,6 +23,8 @@ public class EOSVoiceChat |
|
|
|
|
|
|
|
private string connectedLobbyId; |
|
|
|
public bool IsConnected => lobbyInterface != null && rtcInterface != null && audioInterface != null && !string.IsNullOrEmpty(connectedLobbyId); |
|
|
|
|
|
|
|
private ulong? onConnectionChangedCallbackId, onParticipantStatusChangedCallbackId, onParticipantUpdatedCallbackId; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Provide the required interfaces for voice chat. Product User ID is provided through a callback, so that the
|
|
|
|
@ -59,7 +61,7 @@ public class EOSVoiceChat |
|
|
|
case Result.Success: |
|
|
|
searchHandle.CopySearchResultByIndex(new LobbySearchCopySearchResultByIndexOptions { LobbyIndex = 0 }, out var lobbyDetails); |
|
|
|
|
|
|
|
Debug.Log("Found existing lobby, joining..."); |
|
|
|
Debug.Log("Found existing chat lobby, joining..."); |
|
|
|
lobbyInterface.JoinLobby |
|
|
|
( |
|
|
|
new JoinLobbyOptions |
|
|
|
@ -105,6 +107,7 @@ public class EOSVoiceChat |
|
|
|
connectedLobbyId = data.LobbyId; |
|
|
|
Debug.Log($"Chat lobby creation successful, lobby ID = {connectedLobbyId}"); |
|
|
|
connectArgs.onCompleted?.Invoke(true); |
|
|
|
SubscribeToRoomNotifications(); |
|
|
|
break; |
|
|
|
case Result.LobbyLobbyAlreadyExists: |
|
|
|
// This can happen if two clients try to create the same lobby at the same time, a classic race condition.
|
|
|
|
@ -130,6 +133,7 @@ public class EOSVoiceChat |
|
|
|
connectedLobbyId = data.LobbyId; |
|
|
|
Debug.Log($"Chat lobby joined successfully, lobby ID = {connectedLobbyId}"); |
|
|
|
connectArgs.onCompleted?.Invoke(true); |
|
|
|
SubscribeToRoomNotifications(); |
|
|
|
break; |
|
|
|
default: |
|
|
|
connectedLobbyId = null; |
|
|
|
@ -144,6 +148,9 @@ public class EOSVoiceChat |
|
|
|
if (!IsConnected) |
|
|
|
return; |
|
|
|
|
|
|
|
// Unsubscribing first means we don't get a Disconnected notification for intentionally leaving the lobby
|
|
|
|
UnsubscribeFromRoomNotifications(); |
|
|
|
|
|
|
|
lobbyInterface.LeaveLobby |
|
|
|
( |
|
|
|
new LeaveLobbyOptions |
|
|
|
@ -154,7 +161,7 @@ public class EOSVoiceChat |
|
|
|
null, |
|
|
|
data => { } |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
connectedLobbyId = null; |
|
|
|
} |
|
|
|
|
|
|
|
@ -165,8 +172,14 @@ public class EOSVoiceChat |
|
|
|
{ |
|
|
|
if (!IsConnected) |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: can also disable Sending of data entirely
|
|
|
|
audioInterface.SetAudioInputSettings(new SetAudioInputSettingsOptions |
|
|
|
{ |
|
|
|
LocalUserId = productUserProvider.Invoke(), |
|
|
|
DeviceId = null, // Default input device
|
|
|
|
Volume = muted ? 0f : 100f, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -177,6 +190,8 @@ public class EOSVoiceChat |
|
|
|
{ |
|
|
|
if (!IsConnected) |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -187,6 +202,117 @@ public class EOSVoiceChat |
|
|
|
{ |
|
|
|
if (!IsConnected) |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Set global voice chat volume. Values range between 0.0 (muted) and 1.0 (full volume).
|
|
|
|
/// If desired, volume value can be increased up to 2.0 for an overdrive mode.
|
|
|
|
/// </summary>
|
|
|
|
public void SetOutputVolume(float volume) |
|
|
|
{ |
|
|
|
audioInterface.SetAudioOutputSettings(new SetAudioOutputSettingsOptions |
|
|
|
{ |
|
|
|
LocalUserId = productUserProvider.Invoke(), |
|
|
|
DeviceId = null, // Default output device
|
|
|
|
Volume = volume * 50f, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: handle input/output device changes (keep track of current devices)
|
|
|
|
// TODO: handle participant changes (add/remove users) => also map to platform-specific player IDs
|
|
|
|
// TODO: query local/remote status (is talking or not)
|
|
|
|
|
|
|
|
private void SubscribeToRoomNotifications() |
|
|
|
{ |
|
|
|
var localUserId = productUserProvider.Invoke(); |
|
|
|
|
|
|
|
if (lobbyInterface.GetRTCRoomName( |
|
|
|
new GetRTCRoomNameOptions { LocalUserId = localUserId, LobbyId = connectedLobbyId }, |
|
|
|
out string roomName) != Result.Success) |
|
|
|
{ |
|
|
|
Debug.LogError($"Failed to obtain RTC room name for lobby with ID {connectedLobbyId}"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!onConnectionChangedCallbackId.HasValue) |
|
|
|
{ |
|
|
|
onConnectionChangedCallbackId = lobbyInterface.AddNotifyRTCRoomConnectionChanged |
|
|
|
( |
|
|
|
new AddNotifyRTCRoomConnectionChangedOptions |
|
|
|
{ |
|
|
|
LocalUserId = localUserId, |
|
|
|
LobbyId = connectedLobbyId, |
|
|
|
}, |
|
|
|
null, |
|
|
|
HandleConnectionChanged |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
if (!onParticipantStatusChangedCallbackId.HasValue) |
|
|
|
{ |
|
|
|
onParticipantStatusChangedCallbackId = rtcInterface.AddNotifyParticipantStatusChanged |
|
|
|
( |
|
|
|
new AddNotifyParticipantStatusChangedOptions |
|
|
|
{ |
|
|
|
LocalUserId = localUserId, |
|
|
|
RoomName = roomName, |
|
|
|
}, |
|
|
|
null, |
|
|
|
HandleParticipantStatusChanged |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
if (!onParticipantUpdatedCallbackId.HasValue) |
|
|
|
{ |
|
|
|
onParticipantUpdatedCallbackId = audioInterface.AddNotifyParticipantUpdated |
|
|
|
( |
|
|
|
new AddNotifyParticipantUpdatedOptions |
|
|
|
{ |
|
|
|
LocalUserId = localUserId, |
|
|
|
RoomName = roomName, |
|
|
|
}, |
|
|
|
null, |
|
|
|
HandleParticipantUpdated |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void UnsubscribeFromRoomNotifications() |
|
|
|
{ |
|
|
|
if (onConnectionChangedCallbackId.HasValue) |
|
|
|
{ |
|
|
|
rtcInterface.RemoveNotifyDisconnected(onConnectionChangedCallbackId.Value); |
|
|
|
onConnectionChangedCallbackId = null; |
|
|
|
} |
|
|
|
|
|
|
|
if (onParticipantStatusChangedCallbackId.HasValue) |
|
|
|
{ |
|
|
|
rtcInterface.RemoveNotifyParticipantStatusChanged(onParticipantStatusChangedCallbackId.Value); |
|
|
|
onParticipantStatusChangedCallbackId = null; |
|
|
|
} |
|
|
|
|
|
|
|
if (onParticipantUpdatedCallbackId.HasValue) |
|
|
|
{ |
|
|
|
audioInterface.RemoveNotifyParticipantUpdated(onParticipantUpdatedCallbackId.Value); |
|
|
|
onParticipantUpdatedCallbackId = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void HandleConnectionChanged(RTCRoomConnectionChangedCallbackInfo data) |
|
|
|
{ |
|
|
|
Debug.Log($"RTC Room connection changed, connected = {data.IsConnected}, disconnect reason = {data.DisconnectReason}"); |
|
|
|
// Note: reconnecting is handled automatically by the lobby system
|
|
|
|
} |
|
|
|
|
|
|
|
private void HandleParticipantStatusChanged(ParticipantStatusChangedCallbackInfo data) |
|
|
|
{ |
|
|
|
Debug.Log($"Participant status changed, participant = {data.ParticipantId}, status = {data.ParticipantStatus}"); |
|
|
|
} |
|
|
|
|
|
|
|
private void HandleParticipantUpdated(ParticipantUpdatedCallbackInfo data) |
|
|
|
{ |
|
|
|
Debug.Log($"Participant status changed, participant = {data.ParticipantId}, speaking = {data.Speaking}, audio status = {data.AudioStatus}"); |
|
|
|
} |
|
|
|
|
|
|
|
private class ChatConnectArgs |
|
|
|
@ -202,4 +328,12 @@ public class EOSVoiceChat |
|
|
|
this.maxChatPlayers = maxChatPlayers; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private class ChatUser |
|
|
|
{ |
|
|
|
public readonly ProductUserId productUserId; |
|
|
|
public string platformPlayerId; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |